| Tested on | Red Hat Enterprise Linux 10.2 (Coughlan) |
|---|---|
| Package | podman-5.8.2-5.el10_2.x86_64quay.io/keycloak/keycloak:26.7.3 |
| Applies to | Any Linux host with Podman or Docker |
| Privilege | Keycloak admin access for realm policy and flow inspection; normal user for browser login tests |
| Lab environment | Keycloak 26.7.3 on http://localhost:8080/ — Install Keycloak with Podman |
| Scope | Passwordless architecture in Keycloak 26.7.x: native passkeys and WebAuthn passwordless, external IdP brokering, magic links and email/SMS OTP boundaries, population-specific choices, progressive enrollment, mixed password and passkey rollout, and account recovery design. Does not cover passkey policy click walkthrough, external IdP broker registration, or custom authenticator SPI code. |
| Related guides | Keycloak passkeys and WebAuthn tutorial Keycloak TOTP two-factor authentication Keycloak authentication flows explained Keycloak required actions Keycloak forgot password flow |
Keycloak supports passwordless authentication natively with passkeys and WebAuthn. For a normal Keycloak browser login, native passkeys and WebAuthn are the main built-in passwordless option in Keycloak 26.7.
This guide compares the main ways to implement Keycloak passwordless login on Keycloak 26.7.3. It covers:
- Native passkeys and WebAuthn
- External identity provider brokering
- Extension-based magic links and email or SMS OTP boundaries
- Enrollment, migration, fallback, and account recovery by user population
Step-by-step passkey policy configuration, registration screenshots, and RP ID troubleshooting live in the Keycloak passkeys and WebAuthn tutorial.
How do you implement passwordless authentication in Keycloak?
- Most browser applications: use Keycloak's built-in passkey and WebAuthn passwordless support. The user registers a passkey, such as Windows Hello, Touch ID, a phone passkey, or a FIDO2 security key. On later logins, Keycloak verifies that passkey instead of asking for the user's password.
- Users already on Entra ID, Okta, Google, or another IdP: Keycloak can delegate authentication to that provider through identity brokering.
- Email magic links or email/SMS OTP: Keycloak does not provide these as built-in general-purpose primary login methods. They normally require an extension or custom authenticator.
How does passwordless authentication work in Keycloak?
User opens application
|
v
Application redirects user to Keycloak
|
v
Keycloak login page
|
v
User chooses passkey
|
v
Browser / phone / security key
verifies fingerprint, PIN or face
|
v
Keycloak verifies the WebAuthn credential
|
v
Keycloak signs the user in
|
v
Application receives the
OIDC tokens or SAML responseAfter the diagram above:
- The application does not verify the fingerprint or passkey itself.
- The browser and authenticator perform the WebAuthn ceremony with Keycloak.
- Keycloak then completes the normal application login, such as issuing OIDC tokens or returning a SAML response.
Keycloak acts as the WebAuthn relying party, and its current documentation describes passkey registration and authentication through the WebAuthn passwordless mechanisms.
What passwordless means in Keycloak
Passwordless means the primary login step does not ask the user to type a memorized password. Keycloak still issues its own tokens to applications; passwordless only changes how the user proves identity at the login boundary.
When comparing these options, focus on what actually authenticates the user rather than whether a product describes the experience as "passwordless."
Terminology
| Term | What it means in Keycloak |
|---|---|
| WebAuthn | W3C browser API and authentication standard used by Keycloak for public-key credentials |
| WebAuthn 2FA | WebAuthn credential used after another primary factor |
| WebAuthn passwordless | webauthn-passwordless credential can replace password |
| Passkey | A discoverable WebAuthn credential designed for passwordless authentication and often synchronized across devices |
| Discoverable credential | A WebAuthn credential from which the authenticator can identify the associated account, allowing Keycloak to authenticate the user without asking for the username first |
| Loginless WebAuthn | User authenticates without first submitting a username or password; requires a discoverable credential |
| Authenticator | A Keycloak authentication step that verifies a user, such as password, OTP, or WebAuthn |
| IdP | Identity Provider; another service such as Entra ID, Okta, or Google that authenticates the user |
| Identity brokering | Keycloak redirects authentication to another IdP and trusts the authentication result |
| SPI | Service Provider Interface; Keycloak's extension mechanism used to add custom authenticators and other server behavior |
RP ID (Relying Party ID) identifies the web domain for which a WebAuthn credential is valid. For example, a Keycloak login hosted under login.example.com might use an RP ID such as login.example.com or an appropriate parent domain, depending on the deployment.
Username-less login is a common passkey UX goal: the user clicks Sign in with Passkey or picks a credential from conditional UI without typing a username first. Keycloak resolves the account from the discoverable credential (webauthn-passwordless). That works when users already have a suitable discoverable credential and the WebAuthn RP ID is valid for the Keycloak login origin. During migration, keep username entry available for password fallback and for accounts without enrolled passkeys.
Passwordless versus loginless
Keycloak distinguishes passwordless WebAuthn from loginless WebAuthn. Passwordless authentication can happen after the user has already entered a username. Loginless authentication requires a discoverable credential and skips the username step.
| Pattern | Passwordless primary login? | Why |
|---|---|---|
Passkeys / WebAuthn passwordless (webauthn-passwordless) |
Yes | A WebAuthn credential replaces the password step. Discoverable credentials also allow username-less or loginless authentication. |
| External IdP | Potentially — depends on how the upstream IdP authenticated the user | Keycloak brokers the upstream result; the original method may be password, MFA, SSO session, or passkey |
| Email magic link (extension or custom SPI) | Yes | One-time link or OTP in email replaces password entry |
| TOTP after username/password | No | Second factor only; password remains primary |
WebAuthn as second factor (webauthn) |
No | Password first, security key second |
Application Keycloak login Primary proof
┌────────────┐ ┌─────────────────┐
│ OIDC client│ ─redirect─►│ Browser flow │
└────────────┘ │ evaluates… │
└────────┬────────┘
│
┌─────────────────────────┼─────────────────────────┐
v v v
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Passkey / │ │ Username + │ │ IdP redirect │
│ WebAuthn │ │ password (legacy│ │ (Google, Entra, │
│ passwordless │ │ or bootstrap) │ │ Okta, Apple…) │
└─────────────────┘ └─────────────────┘ └─────────────────┘Keycloak passwordless options
| Method | Built into Keycloak? | Best understood as |
|---|---|---|
| Passkeys / WebAuthn | Yes | Native passwordless browser login |
| External IdP | Yes, through brokering | Authentication delegated elsewhere |
| Magic link | No general built-in login | Extension or custom authenticator |
| Email / SMS OTP | No general built-in primary login | Extension or custom authenticator |
Start with your security and recovery requirements when choosing an authentication method. For example, a requirement for phishing-resistant authentication quickly rules out email magic links as the primary choice for many workforce applications.
Passkeys and WebAuthn
If you want Keycloak itself to handle passwordless browser authentication, passkeys are usually the first built-in option to consider.
A passkey is not another password stored by Keycloak:
- During registration, the authenticator creates a public and private key pair.
- Keycloak stores the public credential information.
- The private key remains with the user's authenticator or passkey provider.
- During login, the authenticator proves possession of that private key without sending it to Keycloak.
Keycloak stores credentials registered through its WebAuthn Passwordless policy as webauthn-passwordless credentials. Passkeys are discoverable WebAuthn credentials that use this passwordless credential type.
For the integrated passkey support in Keycloak 26.7's default login forms, you do not need to add a separate WebAuthn Passwordless Authenticator execution. Custom passwordless or loginless flows can still use that authenticator explicitly.
On Keycloak 26.7.3, enable passkeys under Realm settings → Login → Login Screen Customization → Enable Passkeys (field-level setup and screenshots are in the passkeys tutorial). With passkeys enabled, Keycloak adds conditional UI and a Sign in with Passkey control to the built-in login form.
Workforce pattern:
- Assign Webauthn Register Passwordless through Keycloak required actions or Account Console self-service.
- Keep Username Password Form as an alternative during migration.
- In the default conditional-2FA design, Condition - credential detects that the current authentication already used a passwordless WebAuthn credential, allowing the flow to avoid immediately requiring OTP as another factor.
Before testing username-less login, verify that the realm's passwordless WebAuthn settings are configured as expected. You can verify the same settings through the Admin REST API instead of relying only on the Admin Console. The following check confirms whether passkey support is enabled and shows the RP ID and user-verification policy:
export KC_BASE='http://127.0.0.1:8080'
export REALM='golinuxcloud'
export KC_ADMIN_USER='admin'
read -s KC_ADMIN_PASSWORD
echo
ADMIN_TOKEN=$(curl -sS -X POST "${KC_BASE}/realms/master/protocol/openid-connect/token" \
-d 'grant_type=password' -d 'client_id=admin-cli' \
-d "username=${KC_ADMIN_USER}" -d "password=${KC_ADMIN_PASSWORD}" | \
python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
curl -sS -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${KC_BASE}/admin/realms/${REALM}" | python3 -c "
import sys,json
r=json.load(sys.stdin)
print('passkeysEnabled:', r.get('webAuthnPolicyPasswordlessPasskeysEnabled'))
print('rpId:', r.get('webAuthnPolicyPasswordlessRpId'))
print('userVerification:', r.get('webAuthnPolicyPasswordlessUserVerificationRequirement'))
print('resetPasswordAllowed:', r.get('resetPasswordAllowed'))
"Sample output:
passkeysEnabled: True
rpId: localhost
userVerification: required
resetPasswordAllowed: TruepasskeysEnabled: True confirms that passkey integration is enabled for the realm. A successful login still depends on:
- The authentication flow
- Registered credentials
- RP ID and origin configuration
- Browser support
- Theme or login-form behavior
In production, configure an RP ID that matches the effective domain scope you intend to use, and serve the login origin over HTTPS. localhost is a special development case.
Inspect the bound browser flow next. Passkey primary login coexists with password and conditional second factor in the default tree:
curl -sS -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${KC_BASE}/admin/realms/${REALM}/authentication/flows/browser/executions" | \
python3 -c "
import sys,json
for e in json.load(sys.stdin):
name=e.get('displayName') or e.get('providerId') or e.get('flowAlias') or ''
print(f\"{e.get('requirement',''):12} {name}\")
"Sample output (trimmed to the forms branch):
ALTERNATIVE forms
REQUIRED Username Password Form
CONDITIONAL Browser - Conditional 2FA
REQUIRED Condition - user configured
REQUIRED Condition - credential
ALTERNATIVE OTP Form
DISABLED WebAuthn Authenticator
DISABLED Recovery Authentication Code FormIn a Keycloak authentication flow:
- REQUIRED means the execution must succeed when that path is reached.
- ALTERNATIVE means one successful alternative can satisfy that level of the flow.
- CONDITIONAL means the subflow runs only when its configured conditions match.
Username Password Form stays Required inside forms, while passkeys attach to the same login page when enabled. In Keycloak 26.7's integrated passkey flow, the passkey logic is built into the standard username and password form. A successful passkey authentication can therefore satisfy the login without the user actually submitting the password field. REQUIRED here does not mean every user must type a password.
A user can hold both a password and a passkey. That mixed state is normal during rollout:
USER_ID=$(curl -sS -G -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${KC_BASE}/admin/realms/${REALM}/users" \
--data-urlencode 'username=passkey-lab-user' | \
python3 -c "import sys,json; u=json.load(sys.stdin); print(u[0]['id'])")
curl -sS -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${KC_BASE}/admin/realms/${REALM}/users/${USER_ID}/credentials" | \
python3 -c "import sys,json; [print(c['type']) for c in json.load(sys.stdin)]"Sample output:
password
webauthn-passwordlessHaving both credential types on one account is a common and useful state during progressive migration: passkey-first users can still recover through password reset until you disable passwords for that population.
Workforce passkey architecture (Keycloak-native)
┌──────────────┐ ┌───────────────────────────────┐
│ User browser │────►│ Keycloak browser flow │
└──────────────┘ │ • Existing Keycloak SSO │
│ session (cookie) │
│ • IdP redirect (optional) │
│ • Passkey OR password (forms)│
│ • Conditional OTP/WebAuthn │
│ 2FA │
└───────────────┬───────────────┘
│
┌───────────────v───────────────┐
│ Credentials on user record │
│ webauthn-passwordless │
│ password (until retired) │
│ otp / recovery (fallback) │
└───────────────────────────────┘Phishing resistance: passkeys bind to your RP ID and origin. They resist credential replay on look-alike domains when RP ID and TLS are configured correctly. They do not replace application-level authorization or compromised-session detection.
External identity providers
When customers or employees already authenticate upstream—Entra passkeys, Google account with security key, Okta FastPass, Apple Sign In—identity brokering may be simpler than asking those users to register another WebAuthn credential directly in Keycloak.
Keycloak's Identity Provider Redirector sits early in the browser flow as an Alternative execution:
- Users choose an upstream IdP.
- Keycloak links the federated identity and issues its own tokens to your applications.
- Keycloak brokers the upstream authentication result.
Whether the original authentication was actually passwordless depends on the upstream IdP policy and, where needed, assurance information such as authentication context claims. An upstream passwordless authentication or an existing SSO session may mean the user does not type a password during the Keycloak redirect, but the underlying authentication method is not always known to Keycloak.
Customer / B2C pattern:
- Add OIDC or SAML identity providers (provider registration is out of scope here—see identity provider docs when you configure brokers).
- Expose IdP buttons on the login theme; hide username/password for pure social login if policy allows.
- Map claims with IdP mappers; decide whether Keycloak creates local users on first login.
- Keep a support path for accounts that cannot reach the upstream IdP.
Workforce hybrid pattern:
- Offer corporate IdP (Entra/Okta) and local passkeys for contractors or break-glass accounts.
- Use Organization or Identity-First Login flows when you must route
@company.comaddresses to the corporate broker automatically.
Verify whether the realm already defines brokers before assuming native passkeys are the only path:
curl -sS -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${KC_BASE}/admin/realms/${REALM}/identity-provider/instances" | \
python3 -c "import sys,json; idps=json.load(sys.stdin); print('identityProviders:', len(idps))"Sample output when no identity providers are configured yet:
identityProviders: 0Zero configured brokers means this realm is not currently delegating authentication to an external IdP. Passwordless login would therefore need to come from Keycloak's native WebAuthn or passkey capabilities or an installed custom authenticator.
Customer login via external IdP
┌────────┐ ┌──────────┐ ┌─────────────┐ ┌─────────────┐
│ User │──►│ Keycloak │──►│ Google / │──►│ Keycloak │
│ browser│ │ login │ │ Entra / … │ │ tokens → app│
└────────┘ └──────────┘ └─────────────┘ └─────────────┘
│ │
│ upstream auth │
│ method varies │
└────────────────┘Tradeoffs:
Pros
- Faster rollout
- Upstream provider handles passkey enrollment and recovery
- Keycloak does not need to manage those users' WebAuthn credentials directly
Cons
- Token and session semantics still belong to Keycloak
- An upstream outage can block login for users who depend on that IdP
- Attribute and MFA policy split across two admin planes
| Broker type | Passwordless upstream | Keycloak considerations |
|---|---|---|
| Enterprise OIDC/SAML | Often SSO session or upstream MFA | Map groups from claims; first-broker-login flow; optional HR-driven deprovisioning |
| Social OIDC | Provider password or provider passkey | Higher fraud monitoring; optional step-up for sensitive clients |
| Same realm, both | Mixed populations | Separate login themes or client-specific IdP hints; do not assume one recovery runbook |
For federation versus brokering vocabulary, see Keycloak user federation vs identity brokering—LDAP password validation is not the same as OIDC brokering.
Does Keycloak support magic link authentication?
Not as a built-in general-purpose login method. Keycloak has native action-token emails for workflows such as password reset and required actions, while magic-link primary login normally requires a community or custom authenticator.
Teams usually implement magic links through:
- Community authenticator extensions (magic link or email OTP SPI projects)
- Action tokens via execute-actions email (good for one-time setup tasks, not general daily login)
- Custom authenticator SPI maintained in your organization
An authentication extension becomes part of every login that uses it, so treat it like security-sensitive application code:
- Compatibility with the Keycloak version you are running
- Email deliverability (SPF, DKIM, rate limits, link lifetime)
- Replay protection, single-use semantics, short token lifetime, and any additional contextual checks required by your threat model
- Audit events and admin visibility when links are issued or consumed
Native action tokens power required actions and forgot-password flows—password reset links are not the same product as passwordless primary login, but they share SMTP infrastructure you must harden before any email-based auth.
You do not have to use the same passwordless method for every user. For example, a customer portal might use a magic-link extension for low-friction sign-in while employee accounts use passkeys or a corporate IdP.
Does Keycloak support email or SMS OTP login?
General email or SMS OTP primary login is not the same as Keycloak's built-in TOTP:
- Built-in TOTP: a second factor that runs after primary authentication, usually with a password first.
- Email or SMS OTP login: generally requires an authenticator extension or custom SPI.
- Password-reset or execute-actions email: proves possession of an inbox for a one-time workflow, not daily sign-in.
SMS OTP also carries separate SIM-swap and phishing considerations. Treat it as a product and fraud decision, not a built-in Keycloak toggle.
Which passwordless option should you use?
There is no single passwordless method that fits every user. Employees on managed laptops have different recovery and security requirements from customers signing in occasionally from personal devices.
| Population | Typical primary option | Keep as fallback | Often weak as sole option |
|---|---|---|---|
| Workforce (managed devices) | Keycloak passkeys or corporate IdP broker | Independently accessible second passkey or hardware authenticator, break-glass password | Email magic link alone for high-assurance apps |
| Workforce (BYOD) | Passkeys with cross-platform support, or a corporate IdP broker | Password + step-up OTP during migration | Forcing platform-only passkeys without roaming keys |
| Customer (B2C) | Social/OIDC brokers with upstream MFA | Email magic link extension, SMS OTP (via extension) | Shared kiosk passkeys |
| Mixed legacy + new | Passkeys for early adopters; password fallback for users not yet enrolled | Admin-triggered required actions | Big-bang password disable on day one |
| High-assurance apps | Passkeys + step-up (Keycloak authentication flows explained) | Hardware keys, controlled recovery flows | Passwordless with no recovery story |
Decision flow in plain terms:
- Do these users already sign in through an organization-wide identity provider such as Microsoft Entra ID or Okta? If that system already manages passkeys or MFA, evaluate brokering it into Keycloak before creating another set of credentials.
- Must Keycloak own credentials for this app? If yes, native passkeys or vetted extensions—not both blindly.
- Is email the only channel? Evaluate magic link extensions with clear fraud monitoring.
- Is the client a constrained device? Consider CIBA or the Device Authorization Grant instead of browser passkeys.
How users get their first passkey
The login page is usually the easy part. The harder problem is getting existing users enrolled and making sure they can recover when a passkey is lost.
A Keycloak required action is a task that the user must complete during login before Keycloak finishes the authentication session. Webauthn Register Passwordless uses this mechanism to ask the user to create a passwordless WebAuthn credential.
| Path | How it works | Best for |
|---|---|---|
| Required action after password login | User signs in with password once; Keycloak prompts Webauthn Register Passwordless | Workforce migration |
| Execute-actions email | Admin sends link with webauthn-register-passwordless |
Remote users without help desk visit |
| Account Console self-service | User registers passkey from security settings | Voluntary adoption |
| Default required action on new users | New users are required to register a passwordless WebAuthn credential during onboarding | Greenfield or passkey-first onboarding |
| IdP first login | Broker creates linked account; no Keycloak password | Customer and SSO-first workforce |
If you specifically want no long-term password, that requires your provisioning or onboarding design to avoid issuing one; it is not a property of Webauthn Register Passwordless itself.
List built-in enrollment actions before you automate:
curl -sS -H "Authorization: Bearer ${ADMIN_TOKEN}" \
"${KC_BASE}/admin/realms/${REALM}/authentication/required-actions" | \
python3 -c "
import sys,json
for r in json.load(sys.stdin):
if 'webauthn' in r['alias'].lower() or 'recovery' in r['alias'].lower() or 'otp' in r['alias'].lower():
print(r['alias'], 'enabled='+str(r.get('enabled')))
"Sample output:
CONFIGURE_TOTP enabled=True
webauthn-register enabled=True
webauthn-register-passwordless enabled=True
CONFIGURE_RECOVERY_AUTHN_CODES enabled=TrueAll four actions are available for staged rollout:
- Passkey enrollment
- OTP second factor
- Recovery codes
Assign them independently through the Admin Console or your automation tooling. Assign required actions carefully—requiredActions on a user is a list, and replacing it through the REST API can remove other pending actions.
Migrate from passwords to passkeys gradually
- Keep password login available initially.
- Ask a small group of users to register passkeys.
- Verify that passkey login and recovery both work.
- Expand enrollment to more users.
- Assign passkey registration to the next group of users through required actions when you are ready.
- Require an independent fallback or recovery method before removing password login. If you use recovery codes, test exactly where they sit in your authentication flow; Keycloak's built-in recovery codes are primarily a backup for 2FA.
- Remove password login only for users who are ready.
Mixed population timeline
Phase 1 ──► password + optional passkey enrollment
Phase 2 ──► passkey-preferred; password fallback
Phase 3 ──► password removed only after passkey and recovery are verifiedDuring migration:
- Leave
resetPasswordAllowed: trueuntil help desk processes exist for users without passkeys. - Keep password reset available while passwords remain a supported fallback, unless you have another recovery mechanism.
- Disabling password reset removes the self-service recovery path for users who forget their password; it does not disable password authentication itself.
Account recovery after losing a passkey
A passwordless setup is not complete until you have tested account recovery after the user's primary authenticator is unavailable.
Keycloak stores the public WebAuthn credential, not the private passkey itself. If the user's only authenticator is lost, Keycloak cannot recreate that private key. You must first establish the user's identity through another trusted method and then register a new credential.
Separate identity recovery from credential replacement. A required action such as Webauthn Register Passwordless handles enrollment after Keycloak already knows who the user is—it is not, by itself, account recovery.
Lost only passkey
|
v
How does Keycloak establish the user's identity?
|
v
existing password / alternate IdP / independent second passkey /
verified help-desk recovery / approved account-recovery workflow
|
v
delete lost credential
|
v
Webauthn Register Passwordless
|
v
new passkey| Scenario | Practical response |
|---|---|
| Lost passkey device | Sign in with an independently accessible second passkey, password (if retained), or IdP; after identity is re-established, admin deletes stale webauthn-passwordless credential and re-assigns Webauthn Register Passwordless |
| Lost roaming security key | Same as passkey; ship replacement key and re-register after identity proof |
| Upstream IdP unavailable | Break-glass local account or alternate broker; document offline procedure |
| Magic link not received | SMTP troubleshooting; resend; admin verification out-of-band |
| Passkey removed from authenticator or password manager | Authenticate through another recovery path, remove the stale Keycloak credential if necessary, then register a new passkey |
Keycloak cannot recover private key material—admins delete credentials and re-enroll, as described in the passkeys tutorial.
Layer fallbacks deliberately:
- Recovery authentication codes (
CONFIGURE_RECOVERY_AUTHN_CODES) are backup 2FA credentials. They work through the Recovery Authentication Code Form authenticator and complement OTP or WebAuthn used as a second factor. They do not automatically replace a lost primary passkey in a passwordless browser flow. - TOTP as second factor is not passwordless, but it remains a useful step-up and interim fallback during passkey rollout—see Keycloak TOTP two-factor authentication.
- Forgot password remains relevant while passwords exist; see Keycloak forgot password flow for SMTP and reset tokens.
Prevent downgrade attacks during recovery. Recovery can accidentally become weaker than normal login. An attacker who cannot defeat a passkey should not be able to bypass it simply by choosing "I lost my passkey."
- Do not let someone add a new passkey merely because they can access the user's email. For sensitive applications, require another trusted authentication or help-desk identity-verification step before registering a replacement passkey.
- Log credential removal and required-action assignment in realm events.
- Do not allow email-only reset to immediately register a passkey without re-proofing identity for high-risk apps.
Security and UX checklist
Use this list in design review before production cutover.
Security
- RP ID is valid for the production login origin and intended domain scope; do not carry
localhostor lab IP settings into production - TLS everywhere; WebAuthn secure-context rules satisfied
- User verification required on passwordless policy for workforce realms
- Conditional 2FA subflow tested for passkey, password, and IdP paths
- Broker trust limited to required scopes and mappers; audit federated account linking
- Extension magic links: single-use tokens, short TTL, rate limits, SMTP auth
- Break-glass accounts stored separately with monitoring
UX
- Login page communicates passkey and fallback paths—not passkey-only with no help text
- Enrollment works on mobile browsers users actually carry
- Roaming keys available where platform passkeys are not
- IdP button labels match user expectations (work vs personal account)
- Recovery instructions published before password retirement
- Consistent hostname in bookmarks and emailed links (WebAuthn and action tokens)
Operations
- Metrics: enrollment rate, login method mix, failed WebAuthn ceremonies, reset volume
- Help desk runbook: delete credential, assign required action, verify SMTP
- Upgrade test plan when Keycloak minor versions change WebAuthn defaults
- Extension SPI tested on staging before server upgrades
| Symptom | Common causes | Fix |
|---|---|---|
| Passkey option missing | Passkeys disabled, incorrect WebAuthn policy or RP ID, unsupported or custom login form, or browser or passkey availability | Enable policy; align RP ID and URL with the passkeys tutorial |
| OTP after every passkey login | Missing Condition - credential | Add condition for webauthn-passwordless in conditional 2FA subflow |
| Users locked out after migration | Passwords disabled without recovery | Re-enable fallback; configure explicit recovery; admin re-register |
| IdP login succeeds but app denies | Mapper or role mapping | Fix IdP mappers; check client scopes |
CIBA and device authorization
CIBA and Device Authorization sometimes appear in searches for "passwordless Keycloak," but they solve a different problem: authenticating users when the device requesting access cannot conveniently perform the normal browser login itself.
| Grant | User identified upfront? | Passwordless character | Keycloak native UI |
|---|---|---|---|
| Device Authorization Grant | No — user enters code at verification URI | User may authenticate at phone when verifying | Built-in /device page |
| CIBA | Yes — login_hint names the user |
Approval on authentication device; no password typed on consumption device | Requires authentication channel SPI |
They should not normally be chosen just because you want to replace passwords in a normal web application. See Keycloak CIBA and Keycloak Device Authorization Grant for implementation details.
Summary
- Most web applications: Keycloak's built-in passkey and WebAuthn support is the simplest native way to implement passwordless login.
- Authentication managed elsewhere: external identity providers are useful through brokering.
- Magic links and email or SMS OTP: generally require an extension or custom authenticator.
On Keycloak 26.7.3, a practical rollout keeps password fallback, optional IdP redirects, and conditional second factor available until enrollment and recovery are proven. When you move from strategy to implementation, use the passkeys tutorial for Enable Passkeys and registration steps, and the authentication flows guide when you need custom conditional paths.
References
- Keycloak 26.7 Server Administration Guide — Passkeys
- Keycloak 26.7 Server Administration Guide — Authentication
- Keycloak 26.7 Server Administration Guide — Identity Brokering
- Keycloak 26.7 Server Administration Guide — WebAuthn
- Keycloak 26.7 Release Notes
- W3C Web Authentication (WebAuthn) Level 2
- FIDO Alliance — Passkeys
Frequently Asked Questions
Does Keycloak support passwordless natively?
Yes, for WebAuthn passkeys and passwordless WebAuthn credentials through built-in policy, login UI, and required actions on Keycloak 26.4 and later.
- Email magic links as daily login: not native—add them through extensions or custom authenticators.
- External IdPs: another native path via identity brokering when upstream auth is already passwordless.
Can Keycloak login without a username and password?
Yes. With a discoverable WebAuthn credential, Keycloak can support loginless authentication in which the user submits neither a username nor a password. Keycloak's integrated passkey UI can also offer passkeys directly from the login form.
A separate passwordless flow may still:
- Ask for the username first
- Use WebAuthn only to replace the password
Keycloak documents both models explicitly.
Can Keycloak use email OTP instead of a password?
Not as a built-in primary login method. Keycloak's native TOTP is a second factor, not email OTP sign-in. Passwordless email or SMS OTP login generally requires an extension or custom authenticator. Do not confuse that with password-reset or execute-actions email, which are one-time workflow links.
Are passkeys phishing-resistant?
Passkeys use WebAuthn ceremonies bound to your site's RP ID and origin, which blocks simple password replay on a look-alike domain when RP ID and TLS are configured correctly. They do not stop malware on the user's device, session hijacking after login, or social engineering that tricks users into approving the wrong ceremony on a legitimate site.
Is TOTP passwordless?
No. TOTP in Keycloak is a second factor that runs after primary authentication—usually a password—in the browser flow. It strengthens accounts during migration but does not replace the password step by itself.
Does Keycloak have native magic links?
Not for general login. Keycloak sends action-token links for required actions and password reset, which are one-time email flows—not the same as extension-based magic-link primary login products. Teams that want magic-link sign-in install community SPIs or build custom authenticators.
How do users recover without a password?
Registering an independently accessible second passkey or hardware authenticator is one of the cleanest passwordless fallback options. Other recovery options include:
- An independently accessible corporate IdP
- A controlled temporary-password or help-desk process
- Another recovery flow you explicitly configure
Keycloak recovery authentication codes are primarily designed as backup 2FA credentials, so do not assume they will replace a lost primary passkey in your browser flow. After passkey loss, an administrator deletes the old webauthn-passwordless credential and assigns Webauthn Register Passwordless again once the user's identity has been re-established.

