Account Services

Accounts

The accounts system is a fully featured user account management system with roles based access control and support for third-party and multi-factor authentication schemes for a variety of popular sites and providers.

Concepts

Users

Users can create accounts with the system by creating a User object with this system. Users contain a minimal amount of personally identifiable information (PII). For instance, passwords are stored separately from the primary user object. This is both for simplicity of the system as well as additional protection of sensitive data.

Roles

The roles property of the User document contains the list of Role names that the user is a member or owner of. This makes it more practical to quickly discover the user’s permissions within the larger security system. This list is automatically updated by the system upon any change to a Role document itself.

External IDs

In order to support single-sign on with external authentication providers it is important to link a user’s third-party account id with their AcceleratXR id. These IDs are stored in the externalIds` property as an array of ``<type>:<uid> mappings that indicate which third-party provider is represented along with the universally unique identifier for that provider.

Existing external ID links may be re-associated with another account if a user performs a single-sign on attempt in collaboration with an existing AcceleratXR authentication token.

Verifying Accounts

When a new user is created, the account is considered to be unverified until that user responds to a verification e-mail or text message sent to the contact provided at the time of creation. The verification e-mail contains a short lifespan JWT authentication token that must be provided to the /users/:id/verify endpoint in order to prove the user received the e-mail at the given address.

If a user changes their e-mail address at any future point, they will be required to verify the address again, even if a previous e-mail is specified again.

Admin Account

On system startup, a single user account is automatically created called the admin user. This user is given superuser power within the system to perform any action. The login credentials of this account are logged to the stdout of the service exactly once. It is important to save this information for future reference. Since this is an account with root level access it is highly recommended that this account not be used in daily practice, even when superuser privileges are desired.

Attention

To prevent risk of unauthorized access to the system the default admin account should never be used from an external device. Create another user and add them as a member to one of the default Trusted Roles roles instead.

Secrets

A User Secret is how passwords, API keys, multi-factor authentication and backup codes are defined and stored within the system. They provide a method for user’s to authenticate themselves using a trusted known secret.

Passwords

Users that wish to authenticate via a password can create exactly one secret of type password. Password secrets are hashed using the Argon2 algorithm in memory before being transmitted to the database to ensure maximal protection of the password data.

In the event that a password secret is lost or stolen the /users/:id/recover endpoint can be used to reset the password secret and provide a new one.

API Keys

Application keys are used to provide programmatic access to the sytem on behalf of a user. The API key is a unique string, typically a hash, that is created for purposes of identifying users for programmatic functions. The API key can be provided by the user upon creation, or randomly generated by the service. Once an API key secret is created the value is returned in the response and can never be returned again.

Similar to password secrets, API key secrets are hashed with the Argon2 algorithm in-memory before being transmitted and stored to the database.

Multi-Factor Authentication

Users desiring an extra level of protection may enable multi-factor authentication. Multi-factor authentication is enabled by creating a secret of type mfa. Once created an additional request must be sent to /users/:userId/secrets/:id/enroll containing a valid TOTP code to confirm that the end user has successfully registered their MFA device. Once successfully confirmed, all future authentication requests using a password secret will require MFA validation.

MFA Backup Codes

Additionally, upon successful enrollment of an MFA secret, a set of backup codes are automatically generated and returned to the user for safe keeping. These codes may be used at any time as a one-time authentication password secret. Backup codes are not subject to further multi-factor authentication validation. If all backup codes have been used then the user must recover their account using the /users/:id/recover endpoint.

Device

A device secret is used to provide frictionless single-sign on authentication by trusted devices. This is typically a deterministic hash made by the trusted device using a universally unique identifier. Device secrets are not subject to multi-factor authentication requirements. Similar to password secrets, device secrets are hashed with the Argon2 algorithm in-memory before being transmitted and stored to the database.

Roles

Roles are a method of organizing a collection of users for the purposes of enabling group based permissions within the system. Within the larger security system, user id’s and roles are used to identify permissions via Access Control Lists. The Access Control List is a construct for defining the permissable operations for a given user and/or role on a given system resource.

Users can be a member and/or owner of any number of roles with no restrictions on membership. Once added to a role, the system will add the user’s id to the appropriate property of the Role document as well as the User document’s roles property. This allows easy retrievable of any user’s roles without requiring additional searches.

Members

Users can be assigned as members to a given Role object. A member inherits all permissions of the role to perform actions permissible to that group within the system. Members however only have permission to view Role data and have no permission to modify or delete the role itself.

Owners

A Role owners is a user with full privileges to add, modify and delete a Role, including any and all members, metadata and additional owners. While it is possible to define a user as only an owner of a Role, it is functionally equivalent to being both a member and an owner as the system does not make any distinction between the two. An owner is always a member of the role regardless of whether they are explicitly listed as a member or not.

Trusted Roles

On startup the system will automatically create a set of roles which are considered to be for those users with superuser permissions. These roles are called Trusted Roles and are explicitly declared in the cluster’s configuration setting upon deployment.

Organizations

Attention

Requires license to AcceleratXR Enterprise.

A user Organization is an additional level of abstraction allowing for the grouping of multiple users together into virtual teams.

Members

Each organization has a list of member users. These users have access to any and all resources defined for the organization. While members have permission to view organization data such as other members and owners, they do not have permission to modify or delete an Organization or any of its members.

Owners

An Organization owner is a user in which has full control over the organization itself and all users that are members as well as other owners.

Roles

User roles can be associated with a given organization by prefixing the name of the role with the uid of the organization. This makes it easily possible to define a variety of roles, all specific to different organizations.

By default, a set of roles are automatically created when each organization is created corresponding to the Trusted Roles of the system. This effectively grants any owner of the organization superuser permission to perform any action on behalf of the organization.

In this section you’ll find information regarding all of the fundamental concepts that make up the AcceleratXR user management, authentication and permissions system.

Standard Authentication

Basic

The simplest way to authenticate with the AcceleratXR backend is using Basic authentication via the /auth/password REST API endpoint or via one of the Login() functions in CoreSDK. This endpoint supports authentication using an account’s stored password, api key or device.

The below example shows how to authenticate using this method using a user’s unique name and password.

CoreSDK->LoginPassword(_XPLATSTR("username"), _XPLATSTR("password")).then([](pplx::task<void> task)
{
    try
    {
        // Force the exception to be re-thrown if an error occurred.
        task.get();
    }
    catch (const axr::sdk::Exception& e)
    {
        // Handle error here
    }
});

A successful authentication request will return a valid access token and cookie, or return without an error when using the SDK. Access tokens are typically valid for one hour before they must be refreshed.

Multi-factor Challenge

For users that have enabled multi-factor authentication on their account they may be prompted to enter a time-based one-time password (TOTP) code to retrieve the final access token. The system notifies the user of this requirement by returning a CHALLENGE token after the initial request succeeds. The user then must follow up the initial request with a call to the /auth/totp endpoint or by using the CoreSDK.LoginTotp() function in the SDK.

When calling the the TOTP endpoint the challenge token must be provided in addition to the TOTP code as generated by the user’s registered authenticator app or device.

CoreSDK->SetTotpChallengeCallback(CoreSDK->CreateTask([]()
{
    utility::string_t code;
    // TODO Prompt user to enter TOTP code
    return code;
}));
CoreSDK->LoginPassword(_XPLATSTR("username"), _XPLATSTR("password")).then([](pplx::task<void> task)
{
    try
    {
        // Force the exception to be re-thrown if an error occurred.
        task.get();
    }
    catch (const axr::sdk::Exception& e)
    {
        // Handle error here
    }
});

E-mail

This method is used to easily allow users to authenticate with AcceleratXR via their registered e-mail address. It does not require a password be stored on the account. For that it is considered a password-less authentication method. This method also has the benefit of bypassing any configured multi-factor authentication settings with the account, since it effectively uses a time-based one-time password to function internally.

A user submits an authentication request to the /auth/email/<email> endpoint. The system then sends a message to the e-mail provided (assuming it’s registered) with a time-based one-time password code embedded in the body of the message.

The following example shows the initial request to receive the totp code via e-mail.

CoreSDK->LoginEmail(_XPLATSTR("email")).then([](pplx::task<void> task)
{
    try
    {
        // Force the exception to be re-thrown if an error occurred.
        task.get();
    }
    catch (const axr::sdk::Exception& e)
    {
        // Handle error here
    }
});

Once the code is received the user then submits the provided code to the backend to retrieve the final access token.

CoreSDK->LoginEmail(_XPLATSTR("email"), _XPLATSTR("code")).then([](pplx::task<void> task)
{
    try
    {
        // Force the exception to be re-thrown if an error occurred.
        task.get();
    }
    catch (const axr::sdk::Exception& e)
    {
        // Handle error here
    }
});

Phone

This method is used to easily allow users to authenticate with AcceleratXR via their registered phone number. It does not require a password be stored on the account. For that it is considered a password-less authentication method. This method also has the benefit of bypassing any configured multi-factor authentication settings with the account, since it effectively uses a time-based one-time password to function internally.

A user submits an authentication request to the /auth/phone/<phone> endpoint. The system then sends a text message to the phone number (assuming it’s registered) with a time-based one-time password code embedded in the body of the message.

The following example shows the initial request to receive the totp code via phone.

CoreSDK->LoginPhone(_XPLATSTR("phone")).then([](pplx::task<void> task)
{
    try
    {
        // Force the exception to be re-thrown if an error occurred.
        task.get();
    }
    catch (const axr::sdk::Exception& e)
    {
        // Handle error here
    }
});

Once the code is received the user then submits the provided code to the backend to retrieve the final access token.

CoreSDK->LoginPhone(_XPLATSTR("phone"), _XPLATSTR("code")).then([](pplx::task<void> task)
{
    try
    {
        // Force the exception to be re-thrown if an error occurred.
        task.get();
    }
    catch (const axr::sdk::Exception& e)
    {
        // Handle error here
    }
});

This section provides detail on how to work with the standard built-in authentication methods provided by the AcceleratXR platform out of the box.

SSO Providers

Discord

Coming Soon!

Facebook

Coming Soon!

Google

Coming Soon!

Steam

Coming Soon!

Twitter

Coming Soon!

This section provides detailed explanations of how to work with the supported third-party single sign-on (SSO) providers supported by the AcceleratXR platform.