How do I Enable Multi-Factor Authentication for TrueVault Users?

Your TrueVault end users can protect their data even when their password is stolen by enabling multi-factor authentication (MFA).

If a user has enrolled in MFA, they must provide a time-based MFA code when logging in, as well as their username and password. The MFA secret is stored on a mobile device using an MFA application (Google Authenticator, Authy, etc.). Hackers will not be able to log in as a user unless they have access to the user’s mobile device, as well as the correct username and password. This protects the user from a range of social engineering attacks geared towards stealing passwords. Because of this, we highly recommend allowing all your users to enroll in MFA.

The following tutorial will walk you through how to build an application that will allow a user to enroll, authenticate, and unenroll with MFA.

If you would rather get your hands dirty with some sample code, check out our User MFA Sample App page.

Setup

Create an End User

Let’s create an end user for our application using an administrator user’s API key (by this we mean an API Key for a user that is a member of the FULL_ADMIN group).

Request
curl https://api.truevault.com/v1/users \
    -X POST \
    -u ${ADMIN_API_KEY}: \
    -d "username=bob&password=deadbeef"
Response
{
    "result": "success",
    "transaction_id": "00000000-0000-0000-0000-000000000000",
    "user": {
        "access_key": null,
        "access_token": ".eJwljbsOwjAMAP8lK1hyEru",
        "account_id": "00000000-0000-0000-0000-000000000000",
        "api_key": "00000000-0000-0000-0000-000000000000",
        "id": "00000000-0000-0000-0000-000000000000",
        "status": "ACTIVATED",
        "user_id": "00000000-0000-0000-0000-000000000000",
        "username": "bob",
        "mfa_enabled": false
    }
}

We can see that by default MFA is not enabled for users: "mfa_enabled": false.

For more information, see our documentation on Creating a User.

Create the End User Group

In order for Users to enroll in MFA, we need to add them to a Group with a Policy that allows updating themselves. You can add all your Users to this Group, and they will be able to enroll with MFA. Note because they are allowed to update themselves, that means they will be able to modify their username, password, and attributes in addition to enrolling in MFA. These permissions are probably desirable, unless you store a sensitive internal field like, "paid": true, in their user attributes. If you need this, consider using a Document in a Vault that has more restrictive permissions instead of the User’s attributes.

Policy
[
    {
        "Resources":[
            "User::$[id=self.id]"
        ],
        "Activities":"U"
    }
]
Request
curl https://api.truevault.com/v1/groups \
    -X POST \
    -u ${ADMIN_API_KEY}: \
    -d "name=end_users&user_ids=${BOB_USER_ID}&policy=W3siUmVzb3VyY2VzIjpbIlVzZXI6OnNlbGYiXSwiQWN0aXZpdGllcyI6IlUifV0="
Response
{
  "group": {
    "group_id": "00000000-0000-0000-0000-000000000000",
    "id": "00000000-0000-0000-0000-000000000000",
    "name": "end_users",
    "policy": [
      {
        "Activities": "U",
        "Resources": [
          "User::$[id=self.id]"
        ]
      }
    ],
    "user_ids": [
      "00000000-0000-0000-0000-000000000000"
    ]
  },
  "result": "success",
  "transaction_id": "00000000-0000-0000-0000-000000000000"
}

For more information on using Groups, see our Groups API documentation.

Adding User MFA to your Application

Starting MFA Enrollment

Now that the user is in the appropriate Group, they should be able to enroll in MFA. In your application you will need to create a view that will interact with the TrueVault API in order to enroll for MFA. When loading this view, call the following endpoint to retrieve MFA information for the User:

Request
POST /v1/users/(string: user_id)/mfa/start_enrollment

Authorization: \* ACCESS_TOKEN of user enrolling with MFA *\
Response

JSON Parameters:

{
    "result": "success",
    "transaction_id": "00000000-0000-0000-0000-000000000000",
    "user_mfa": {
        "qr_code_svg": string,
        "secret": string,
        "uri": string
    }
}

 

We return a QR code which can be displayed in your view using this HTML div:

<img src="data:image/svg+xml;base64,\* qr_code_svg *\">

You can also consume uri to create your own QR code image client-side. Finally, we recommend that you display the MFA secret to your users in text form so that they can manually add it to their application in case they cannot use the QR code.

For more information, see our documentation on Starting MFA Enrollment for a User.

Finalizing MFA Enrollment

Once the user has added the MFA secret to their MFA application, they need to complete their enrollment by submitting two successive MFA codes that are generated by the MFA app. You need to create a form for them to submit these two codes by calling this endpoint:

Request
POST /v1/users/(string: user_id)/mfa/finalize_enrollment

Authorization: \* ACCESS_TOKEN of user enrolling with MFA *\
Content-Type: application/json

JSON Parameters:

{
    "mfa_code_1": string,
    "mfa_code_2": string
}

 

Response
{
    "result": "success",
    "transaction_id": "00000000-0000-0000-0000-000000000000"
}

For more information, see our documentation on Finalizing MFA Enrollment for a User.

Logging in with MFA

Once the user has successfully finalized their MFA enrollment, they must provide an MFA code when logging in:

Request
POST /v1/auth/login

Form Parameters:
* username - string
* password - string
* account_id - string
* mfa_code - string
Response
{
    "result": "success",
    "transaction_id": "00000000-0000-0000-0000-000000000000",
    "user": {
        "access_token": ".eJwljbEKwjAaSF93Fdsx",
        "account_id": "00000000-0000-0000-0000-000000000000",
        "id": "00000000-0000-0000-0000-000000000000",
        "status": "ACTIVATED",
        "user_id": "00000000-0000-0000-0000-000000000000",
        "username": "bob",
        "mfa_enabled": true
    }
}

If the user is enrolled with MFA and does not provide an MFA code, they will receive an error:

{
    "result": "error",
    "transaction_id": "00000000-0000-0000-0000-000000000000",
    "error": {
        "message": "MFA code is required for this MFA-enrolled user",
        "type": "USER.MFA_CODE_REQUIRED"
    }
}

For more information, see our documentation on User Login.

Unenrolling from MFA

In order to let users unenroll from MFA, you need to create another view where users must enter their password and an MFA code. This view should call this endpoint:

Request
POST /v1/users/(string: user_id)/mfa/unenroll

Authorization: \* ACCESS_TOKEN of user enrolling with MFA *\
Content-Type: application/json

JSON Parameters:

{
    "mfa_code": string,
    "password": string
}

 

Response
{
    "result": "success",
    "transaction_id": "00000000-0000-0000-0000-000000000000"
}

For more information, see our documentation on Unenrolling MFA for a User.

Conclusion

We just walked through everything you need to do to enable MFA for your end users.

Have more questions? Try asking on StackOverflow and tag your question with truevault.