Skip to main content
Version: Next

TOTP Authenticator

TOTP, or time-based one-time password, is the short numeric code generated by an authenticator app. During enrollment, O2ID creates a per-user secret and returns an otpauth:// setup URI. The user scans that URI in their authenticator app, and the app uses the shared secret plus the current time to generate new codes.

O2ID stores each user's TOTP enrollment data encrypted per tenant. At sign-in, a flow can ask for a TOTP code after another step, such as password verification. O2ID verifies the submitted code against the user's verified TOTP enrollment; there is no delivery connection because nothing is sent over email, SMS, or push.

Configure TOTP in a tenant

First, confirm that the tenant has the built-in totp type available:

o2idctl authenticators list types

Create a tenant authenticator instance:

o2idctl authenticators create --type totp --display-name "Company TOTP" \
--field issuer=Acme

The response includes the authenticator ID. Use that ID in flow definitions and when enrolling users.

Useful TOTP fields:

FieldDefaultDescription
issuerO2IDName shown before the colon in the user's authenticator app — set this to your own deployment's name
accountNameO2ID userFallback account label, used only when a flow enrolls a user before an identifier authenticator has resolved who they are
digits6Number of digits in generated codes
period30Code validity window in seconds
skew1Number of adjacent time windows accepted during verification
progressiveEnrollmentfalseWhen true, an authenticator node referencing this authenticator enrolls a user who has no verified enrollment yet instead of failing their code — see Flow Definition Schema

The label after the colon is normally filled in automatically at enrollment time, from the signed-in user's username — so an authenticator configured with issuer=Acme shows up as Acme:alice, not a generic label shared by every enrollee.

List configured authenticators:

o2idctl authenticators list

Update or disable the TOTP authenticator:

o2idctl authenticators update <authenticator-id> --display-name "Production TOTP"
o2idctl authenticators update <authenticator-id> --enabled false

Use TOTP in a flow

Reference the configured authenticator ID from an authenticator node:

{
"totp": {
"type": "authenticator",
"onSuccess": "allow",
"onFailure": "totp",
"properties": {
"authenticatorId": "<authenticator-id>",
"maxAttempts": 5,
"onLockout": "deny"
}
}
}

See Flows for a complete login flow example.