Keycloak multi-factor authentication with OTP, WebAuthn and conditional MFA
Every Keycloak realm can ask for a second factor at sign-in. This page shows where each factor lives in the admin console, the realm settings behind it, and how to ask for it only where it matters.
21-day trial, no card required. · Runs on managed Keycloak.
Does Keycloak support multi-factor authentication?
Yes. Keycloak supports MFA out of the box with two kinds of second factor: OTP codes from TOTP and HOTP authenticator apps, and WebAuthn security keys and passkeys. Each factor is a step in the realm's authentication flow, so you decide where it runs. Conditional sub-flows ask for the second factor only from certain users, roles or clients, and step-up authentication asks for it again before a sensitive action.

OTP with authenticator apps
Keycloak's OTP factor accepts time-based (TOTP) and counter-based (HOTP) codes from apps such as Google Authenticator, Microsoft Authenticator and FreeOTP. You set the code format for the whole realm under Authentication then Policies then OTP Policy: the type, the hash algorithm, six or eight digits, the period and the look-ahead window. The defaults, TOTP with SHA1, six digits and a 30 second period, work with every common app.
Users register an app through the Configure OTP action under Authentication then Required actions, and turning on its Set as default action switch asks every new user to do so at their next sign-in. In the default browser flow under Authentication then Flows, the OTP Form sits in the Browser - Conditional 2FA sub-flow, which asks for a code from every user who has registered one.
{
"otpPolicyType": "totp",
"otpPolicyAlgorithm": "HmacSHA1",
"otpPolicyDigits": 6,
"otpPolicyPeriod": 30,
"otpPolicyLookAheadWindow": 1,
"otpPolicyCodeReusable": false
}WebAuthn security keys and passkeys
WebAuthn lets a user confirm a sign-in with a security key, or with a passkey kept on their phone, laptop or password manager, and Keycloak uses it in two ways. As a second factor, the user types a password and then confirms with the key: enable Webauthn Register under Authentication then Required actions, and set WebAuthn Authenticator to Alternative in the Browser - Conditional 2FA sub-flow under Authentication then Flows. Its settings are under Authentication then Policies then Webauthn Policy.
For a passkey sign-in with no password, switch on Enable Passkeys under Realm settings then Login, and enable Webauthn Register Passwordless under Required actions. Since Keycloak 26.4 the default login form then offers passkeys through browser autofill and a Sign in with Passkey button, using the settings under Authentication then Policies then Webauthn Passwordless Policy.
{
"webAuthnPolicyPasswordlessRpEntityName": "Example",
"webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256", "RS256"],
"webAuthnPolicyPasswordlessUserVerificationRequirement": "required",
"webAuthnPolicyPasswordlessPasskeysEnabled": true
}Conditional and step-up MFA
A conditional sub-flow runs its second factor only when the condition steps at its top are true. Under Authentication then Flows, duplicate the browser flow, add a sub-flow set to Conditional, and start it with a condition: Condition - user role to ask only admins, Condition - client scope to ask only in clients that carry a given client scope, or Condition - user attribute for a group of users. The OTP Form or WebAuthn Authenticator after the condition is then asked only of the users it matches. Bind the copy as the realm's browser flow, or override it for one client in that client's Advanced tab.
Step-up authentication asks for a stronger factor before a sensitive action. Map ACR values to levels of authentication under Realm settings then General, give each level a sub-flow that starts with Condition - Level of Authentication, and have your application request the level it needs with the acr_values parameter. A user who signed in with a password alone is asked for the second factor only when they reach the action that needs it.
"authenticatorConfig": [
{
"alias": "admins-only",
"config": { "condUserRole": "admin", "negate": "false" }
},
{
"alias": "step-up-level-2",
"config": { "loa-condition-level": "2", "loa-max-age": "300" }
}
]Enterprise Capabilities
Everything you need for secure, scalable authentication
TOTP and HOTP codes
Codes from Google Authenticator, Microsoft Authenticator, FreeOTP and other standard authenticator apps.
Security keys
WebAuthn hardware keys as a second factor after the password.
Passkeys
Sign-in with a passkey and no password, offered by the default login form since Keycloak 26.4.
Conditional MFA
A second factor only for the roles, clients or users you choose.
Step-up authentication
A stronger factor before a sensitive action, requested with ACR values.
Recovery codes
One-time backup codes for users who lose their authenticator.
Go Live in 3 Steps
From zero to production in minutes, not months
Create Your Instance
Sign up and deploy your Keycloak instance. One click, fully managed.
2 minutesCustomize Your Branding
Add your logo, colors, and styling to make login pages match your brand.
5 minutesIntegrate Your App
Use existing Keycloak SDKs or standard OIDC/SAML libraries for any framework.
15 minutesNo credit card required. 21-day free trial with full access.
Frequently Asked Questions
Does Keycloak support SMS for MFA?
Can I require MFA only for admins?
Should I use passkeys or OTP?
Related Features
Complement your setup with these capabilities
Ready to Get Started?
Start your free trial today. Full access to all features for 21 days.