Multi-Factor Authentication¶
Raise the bar from "something you know" to "something you have" — and prove who's really signing in.
What it is¶
Helix IAM offers a broad, modern set of authentication factors that you compose into your sign-in flows. You decide which factors a realm or application accepts, whether they're required for everyone, and whether they're requested conditionally as a step-up only when the moment calls for it.
Available factors¶
| Factor | Description | Learn more |
|---|---|---|
| TOTP | Time-based one-time passcodes from an authenticator app | OTP factors |
| SMS-OTP | One-time passcode delivered by text message | OTP factors |
| Email-OTP | One-time passcode delivered by email | OTP factors |
| HOTP | Counter-based one-time passcodes | OTP factors |
| WebAuthn passkeys (FIDO2) | Phishing-resistant platform & roaming authenticators | Passkeys |
| Recovery codes | Single-use backup codes for account recovery | OTP factors |
| Magic-link passwordless email | Sign in by clicking a one-time link | OTP factors |
| Mobile device push | Approve sign-in on an enrolled phone | Device push |
Step-up authentication¶
A flow can require an additional factor conditionally rather than for every login. Helix carries step-up challenge state through the flow, so a journey can authenticate a user with a primary factor and then demand a second factor only when a condition is met — for example a sensitive application, a high-value transaction, or an elevated risk signal.
Conditional beats mandatory
Requiring a second factor on every action creates friction. Use step-up to ask for stronger proof only where it matters, and keep everyday sign-in fast.
How it works¶
- Choose which factors a realm/application accepts.
- Add the factor as a step in your sign-in journey, setting its requirement (required, alternative, or conditional).
- Users enrol their factor — from the account console or via a Required Action at next login.
- At sign-in, the flow engine challenges for the factor and, where configured, applies step-up only when the condition fires.
In the console¶
The MFA screens live under Authentication → MFA (Overview, TOTP & OTP factors, Passkeys, Device push). Factors are placed in a flow; whether MFA is mandatory realm-wide is a realm setting.
- Open Authentication → Flow editor and add the factor as a step in your sign-in journey.
- Set the step's requirement — required for everyone, or conditional to challenge only as a step-up.
- To require MFA across the whole realm, turn on Require MFA under Authentication → Password policy & lockout (the
requireMfarealm setting). - To force enrolment, add the matching Required Action (for example, configure OTP) on the user.
Always offer a recovery path
Pair any "have" factor with recovery codes or a second enrolled device so a lost phone or token doesn't lock users out. See OTP factors for recovery codes.
Over the API¶
MFA is composed from two API surfaces: the authenticator registry (which factors exist) and flows (where you place them). Whether MFA is mandatory realm-wide is the requireMfa field of the realm-settings resource. The examples assume you have set $HELIX_URL / $REALM and logged in — see Authenticating to the API.
List the available factors¶
Each authenticator reports a factorClass and a level of assurance (levelOfAssurance) — a higher LoA is a stronger factor, which lets a risk-based flow demand step-up to a minimum strength.
[
{ "id": "otp", "displayName": "One-Time Password (TOTP)", "factorClass": "POSSESSION", "levelOfAssurance": 2 },
{ "id": "sms-otp", "displayName": "One-Time Code (SMS)", "factorClass": "POSSESSION", "levelOfAssurance": 2 },
{ "id": "email-otp", "displayName": "One-Time Code (Email)", "factorClass": "POSSESSION", "levelOfAssurance": 2 },
{ "id": "hotp", "displayName": "One-Time Password (HOTP)", "factorClass": "POSSESSION", "levelOfAssurance": 2 },
{ "id": "recovery-code", "displayName": "Recovery Code", "factorClass": "POSSESSION", "levelOfAssurance": 1 },
{ "id": "webauthn", "displayName": "Passkey (WebAuthn)", "factorClass": "POSSESSION", "levelOfAssurance": 3 },
{ "id": "push", "displayName": "Push Approval", "factorClass": "POSSESSION", "levelOfAssurance": 6 }
]
Require MFA realm-wide¶
requireMfa is one field of the realm-settings resource. PUT /settings takes the full object — read it first, then submit the whole document (see password policy for the full pattern).
Wire a factor into a flow¶
Adding a second-factor step is a flow edit — place the authenticator's id (for example otp or webauthn) in the execution tree with the requirement you want (REQUIRED or CONDITIONAL). See Authentication flows → Over the API.
Full endpoint set¶
Method & path (under /admin/realms/{realm}) |
Purpose |
|---|---|
GET /authenticators |
List available factors and their level of assurance |
GET /flows/{alias} · PUT /flows/{alias} |
Read / save the execution tree that places a factor |
GET /settings · PUT /settings |
Read / update requireMfa and other realm policy |