Time-based One-time Password (TOTP)

Configuring TOTP

TOTP is not enabled in Keystone by default. To enable it add the totp authentication method to the [auth] section in keystone.conf:

methods = external,password,token,oauth1,totp

For a user to have access to TOTP, he must have configured TOTP credentials in Keystone and a TOTP device (i.e. Google Authenticator).

TOTP uses a base32 encoded string for the secret. The secret must be at least 128 bits (16 bytes). The following python code can be used to generate a TOTP secret:

import base64
message = '1234567890123456'
print base64.b32encode(message).rstrip('=')

Example output:


This generated secret can then be used to add new ‘totp’ credentials to a specific user.

Create a TOTP credential

Create totp credentials for user:


curl -i \
  -H "Content-Type: application/json" \
  -d '
    "credential": {
        "blob": "'$SECRET'",
        "type": "totp",
        "user_id": "'$USER_ID'"
}' \
  http://localhost:5000/v3/credentials ; echo

Google Authenticator

On a device install Google Authenticator and inside the app click on ‘Set up account’ and then click on ‘Enter provided key’. In the input fields enter account name and secret. Optionally a QR code can be generated programmatically to avoid having to type the information.

QR code

Create TOTP QR code for device:

import qrcode

uri = 'otpauth://totp/{name}?secret={secret}&issuer={issuer}'.format(

img = qrcode.make(uri)

In Google Authenticator app click on ‘Set up account’ and then click on ‘Scan a barcode’, and then scan the ‘totp.png’ image. This should create a new TOTP entry in the application.

Authenticate with TOTP

Google Authenticator will generate a 6 digit PIN (passcode) every few seconds. Use the passcode and your user ID to authenticate using the totp method.


Get a token with default scope (may be unscoped) using totp:


curl -i \
  -H "Content-Type: application/json" \
  -d '
{ "auth": {
        "identity": {
            "methods": [
            "totp": {
                "user": {
                    "id": "'$USER_ID'",
                    "passcode": "'$PASSCODE'"
}' \
  http://localhost:5000/v3/auth/tokens ; echo