Skip to content

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

  1. Choose which factors a realm/application accepts.
  2. Add the factor as a step in your sign-in journey, setting its requirement (required, alternative, or conditional).
  3. Users enrol their factor — from the account console or via a Required Action at next login.
  4. 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.

  1. Open Authentication → Flow editor and add the factor as a step in your sign-in journey.
  2. Set the step's requirement — required for everyone, or conditional to challenge only as a step-up.
  3. To require MFA across the whole realm, turn on Require MFA under Authentication → Password policy & lockout (the requireMfa realm setting).
  4. 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.

curl -s -b cookies.txt "$HELIX_URL/admin/realms/$REALM/authenticators"
[
  { "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).

curl -s -b cookies.txt "$HELIX_URL/admin/realms/$REALM/settings" | grep -o '"requireMfa":[^,]*'
"requireMfa":false

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

See also