WebAuthn Support in Keycloak
How the world's most popular open-source identity server lets your users log in with a fingerprint, a face scan, or a security key — and quietly kills the password in the process.
Imagine walking up to your front door and instead of digging through your pocket for a key, the door simply recognizes your face and clicks open. No key to lose, no key to copy, no key for a burglar to steal from under the doormat. That is roughly what WebAuthn does to the login page. And Keycloak — the identity server that sits behind countless banks, hospitals, government portals, and SaaS products — has built full support for exactly this kind of “no password, just you” login. This chapter-by-chapter guide walks through what WebAuthn actually is, how Keycloak wires it into a real login flow, what happens under the hood on every click, and how to run it safely and reliably in production. No prior security background is assumed; every new term is explained the moment it appears.
1Core Concepts
What is WebAuthn?
WebAuthn (Web Authentication) is a web standard, published by the World Wide Web Consortium (W3C) together with the FIDO Alliance, that lets a website ask your browser to prove who you are using a physical device — a fingerprint sensor, a face scan, a PIN tied to your laptop, or a small USB/NFC security key — instead of a typed password. It is the technology behind the “passkey” buttons you now see on Google, Apple, Amazon, and thousands of other sites. WebAuthn is part of a broader specification called FIDO2, which pairs WebAuthn (the browser-to-website part) with a companion protocol called CTAP (Client to Authenticator Protocol, the browser-to-device part).
A password is like shouting a secret phrase across a room — anyone close enough can hear it, memorize it, and repeat it back later to impersonate you. WebAuthn is like a wax seal on a letter: you press your unique signet ring (your fingerprint or device) onto the wax, and anyone can verify the seal is genuine just by looking at it, but nobody can forge a new letter with it because they don’t own the ring. The “secret” — your private key — never leaves the ring.
Why does WebAuthn exist?
Passwords fail in three predictable ways: people reuse them across sites, attackers steal them through fake “phishing” login pages that look real, and databases holding millions of passwords get breached and leaked. WebAuthn was designed to remove all three failure modes at once. It uses public-key cryptography — a mathematical technique where a matched pair of keys is generated: a private key that never leaves your device, and a public key that is shared freely with the website. Because the private key never travels over the network and never gets typed anywhere, it cannot be phished, leaked from a server breach, or reused across sites — each site gets a completely different key pair.
Where does Keycloak fit in?
Keycloak is a free, open-source Identity and Access Management (IAM) server originally built by Red Bear engineers and now an independent Cloud Native Computing Foundation project. Its job is to be the single front door that every application in a company routes its login through, instead of each application inventing its own login page and password database. Keycloak already understood usernames, passwords, one-time codes, and social logins (Google, GitHub, and so on); WebAuthn support means Keycloak can now also stand at that front door and say “show me your fingerprint” instead of “type your password,” while every connected application keeps working exactly the same way.
Any organization using Keycloak to protect an internal HR portal, a customer banking app, a hospital patient system, or a SaaS dashboard can turn on WebAuthn in the admin console and immediately offer every user a “Sign in with your fingerprint” option — with zero changes to the applications themselves.
Key vocabulary, explained simply
Relying Party (RP)
The website or service asking “who are you?” — in this guide, that is Keycloak itself, acting on behalf of the applications behind it.
Authenticator
The physical thing that holds your private key and proves your identity — your phone’s fingerprint sensor, your laptop’s Face ID, or a USB security key like a YubiKey.
Credential
The key pair created for one specific website. You get a brand-new, unrelated credential for every site you register with — your banking site’s key cannot be reused on a shopping site.
Attestation
A signed statement from the authenticator’s manufacturer, proving the device is genuine hardware and not a piece of malicious software pretending to be one.
Assertion
The signed proof the authenticator sends back every time you log in afterward, confirming “yes, this is the same private key holder as before.”
Passkey
The marketing-friendly name for a WebAuthn credential that can also sync across a person’s devices via their phone or laptop maker’s cloud account.
2Architecture & Components
At a high level, four parties are involved whenever someone logs into a Keycloak-protected application using WebAuthn: the user’s browser, the authenticator (the fingerprint sensor or security key), the Keycloak server acting as the Relying Party, and the application the user is actually trying to reach (called the “client” in Keycloak’s vocabulary). Keycloak itself is broken into a few internal pieces that specifically handle WebAuthn.
graph TB
U[User] -->|touches sensor| A[Authenticator
fingerprint / security key]
A -->|CTAP protocol| B[Browser
WebAuthn API]
B -->|HTTPS / JavaScript| K[Keycloak Server]
K --> AF[Authentication Flow Engine]
K --> CS[Credential Store
public keys only]
K --> AE[Admin Event Logger]
K -->|issues token| APP[Protected Application]
U -->|opens| APP
APP -->|redirects to login| K
Component breakdown
Authentication Flow Engine
Keycloak’s internal workflow builder. WebAuthn is added as a step (“execution”) inside a flow, alongside or instead of the password step, so admins can mix and match — for example, “password OR WebAuthn” or “password AND WebAuthn” for extra-sensitive apps.
Credential Store
Keycloak’s database table that stores, per user, the public key, a device label, the credential ID, and a sign-count — never a private key, because the private key never leaves the user’s authenticator.
WebAuthn Policy
A realm-wide (or per-browser-flow) configuration object controlling things like which security key brands are trusted, whether a PIN is required, and how strict device verification must be.
Browser JavaScript Adapter
A small script Keycloak’s login page loads that calls the browser’s built-in navigator.credentials API — the actual bridge between a web page and the operating system’s authenticator prompt.
Where WebAuthn Policy lives in the admin console
Inside the Keycloak Admin Console, an administrator opens Authentication → Policies → WebAuthn Policy for standard logins, and a separate WebAuthn Passwordless Policy tab for fully passwordless setups. Each has its own settings, because a company might want a lenient policy for “second factor after password” but a strict one for “this alone proves who you are.”
Why does Keycloak use the browser’s own API instead of building its own?
WebAuthn deliberately lives inside the browser itself (Chrome, Safari, Firefox, Edge all ship it natively) rather than as a plugin a website installs. This matters architecturally: Keycloak never touches your fingerprint data, never sees your device’s secure hardware, and never processes biometric information at all. It only ever receives a signed mathematical proof from the browser. This is why Keycloak’s WebAuthn feature can be enabled with configuration, not custom biometric-handling code — the heavy lifting is done by the operating system and the browser, and Keycloak’s role is closer to a strict inspector checking a signed document than a biometric processor.
Think of an airport passport check. The immigration officer (Keycloak) never touches your actual fingerprint scanner data or your government’s ID-issuing database directly — they just check that the passport (the signed assertion) was issued by a trusted authority and matches the person standing in front of them. The messy biometric capture happened somewhere else entirely, at a passport office (your device’s secure hardware).
3Internal Working
Registration — creating a new credential
When a user first turns on WebAuthn for their account, Keycloak’s server generates a random challenge — essentially a one-time, unguessable string of bytes — and sends it to the browser along with some details about the user and the realm. The browser passes this to the authenticator through the CTAP protocol. Inside the authenticator’s secure hardware, a brand-new public/private key pair is generated specifically for this Keycloak realm. The private key is sealed inside the device and will never be exported. The authenticator signs the original challenge using the new private key, producing proof that this exact device generated this exact key pair right now, and sends the public key plus the signed proof back through the browser to Keycloak. Keycloak verifies the signature, checks the attestation (if configured to), and stores the public key against the user’s account.
Authentication — proving you still hold the private key
On every future login, Keycloak again generates a fresh, random challenge. This time it also sends the list of credential IDs already registered to that user (or, for fully passwordless “discoverable” logins, no list at all — more on this in the next chapter). The browser forwards the challenge to the authenticator. The user unlocks the authenticator (touch, face, PIN), the device locates the matching private key, and signs the challenge with it. This signed assertion travels back to Keycloak, which looks up the matching public key it stored during registration and mathematically verifies that the signature could only have been produced by the corresponding private key. If it checks out, the user is authenticated — without a password ever being typed, transmitted, or even existing for this login method.
The sign-counter — Keycloak’s cloning detector
Every WebAuthn authenticator maintains a small internal counter that increases by at least one on every successful authentication. Keycloak stores the last counter value it saw for each credential. If a login arrives with a counter value equal to or lower than the last one stored, Keycloak treats this as a red flag — it usually means the private key has somehow been cloned onto a second, malicious device, since a genuine, single physical authenticator’s counter can only go up. Keycloak can be configured to reject such logins outright.
Some newer authenticators (particularly platform authenticators tied to synced passkeys) deliberately keep their counter frozen at zero, because the whole point of a synced passkey is that the “same” credential legitimately exists on multiple devices. Keycloak’s WebAuthn policy has to be configured to tolerate this rather than flagging every synced-passkey login as suspicious.
Step-by-step: what happens internally, in order
Realm and flow lookup
Keycloak identifies which realm the user belongs to and which authentication flow applies to this login page.
Challenge generation
A cryptographically random challenge is created server-side and cached briefly against the user’s login session.
Browser hand-off
The challenge, relying-party ID (Keycloak’s domain), and allowed credential list are sent to the browser’s WebAuthn JavaScript API.
User presence and verification
The operating system prompts the user to touch a sensor, look at the camera, or enter a device PIN.
Signature creation
The authenticator signs the challenge with the private key and returns the signature, credential ID, and sign-counter.
Server-side verification
Keycloak checks the signature against the stored public key, validates the origin and challenge match, and checks the counter.
Session and token issuance
On success, Keycloak marks the authentication step complete and, once all required steps in the flow pass, issues tokens to the application.
4Data Flow & Lifecycle
sequenceDiagram
participant User
participant Browser
participant Authenticator
participant Keycloak
participant App as Application
User->>App: Clicks "Login"
App->>Keycloak: Redirects to login page
Keycloak->>Browser: Sends challenge + credential options
Browser->>Authenticator: navigator.credentials.get()
Authenticator->>User: Prompts fingerprint / PIN
User->>Authenticator: Provides biometric / PIN
Authenticator->>Browser: Signed assertion
Browser->>Keycloak: Sends signed assertion
Keycloak->>Keycloak: Verifies signature vs stored public key
Keycloak->>App: Redirects with authorization code
App->>Keycloak: Exchanges code for tokens
Keycloak->>App: Access token + ID token
App->>User: Shows logged-in dashboard
Notice something important in that diagram: the application itself never sees the fingerprint, the private key, the assertion, or any WebAuthn detail at all. It only ever receives an authorization code and, later, standard tokens (using OpenID Connect, the protocol Keycloak speaks with applications). This separation is deliberate and central to Keycloak’s whole design — WebAuthn is a concern between the browser and Keycloak; the application only cares about the end result, a proven identity.
The lifecycle of a single credential
Enrollment
A user, usually already logged in via password, visits their account console and adds a security key or device as a new WebAuthn credential.
Active use
The credential is used repeatedly for login; each use updates the sign-counter and the “last used” timestamp stored by Keycloak.
Re-labeling
Users can rename a credential — “Work laptop,” “YubiKey on keyring” — purely for their own bookkeeping; this label is never sent to the authenticator.
Revocation
If a device is lost or stolen, the user (or an admin, on their behalf) deletes the credential from Keycloak’s stored list; the public key is discarded and can never be used to log in again.
Revocation only removes Keycloak’s copy of the public key. It does not, and cannot, delete the private key sitting inside the lost device’s secure hardware — but that is fine, because a private key with no matching registered public key is useless for logging in anywhere Keycloak is checking.
Two flavors of data flow: second-factor vs. passwordless
Keycloak supports WebAuthn in two distinct data-flow shapes. In second-factor mode, the browser first sends a username and password as normal, and only after that succeeds does Keycloak ask for the WebAuthn assertion — two separate round-trips, two separate proofs. In passwordless (discoverable credential) mode, the user does not type a username at all; the browser asks the authenticator “which of your stored credentials matches this website?” and the authenticator itself supplies both the identity and the signed proof in one round-trip. This is what makes true one-touch, no-typing login possible.
5Advantages, Disadvantages & Trade-offs
Advantages
- Phishing-resistant by design — a credential is cryptographically bound to the exact domain it was created for, so it simply will not work on a look-alike fake login page
- Nothing secret is stored on the server; a stolen Keycloak database exposes only public keys, which are useless to an attacker without the matching private key
- No password to forget, reuse, or type into the wrong place
- Much faster login experience — a touch or glance replaces typing a password and possibly a one-time code
- Works across ecosystems — Windows Hello, Apple’s Touch ID/Face ID, Android biometrics, and dedicated USB keys all speak the same standard
Disadvantages & Trade-offs
- Device loss becomes a real recovery problem — if a user’s only authenticator is lost and no backup credential or recovery flow exists, they are locked out
- Older browsers and some legacy corporate devices lack WebAuthn support entirely
- Passwordless mode requires careful account-recovery design, since there is no password to fall back on
- Admins must decide policy on attestation, credential types, and counter handling — misconfiguration can be either too lax or too restrictive
- Shared or kiosk-style workstations do not fit the WebAuthn model naturally, since it assumes a personal device
Switching to WebAuthn is a bit like replacing a house key with a fingerprint lock. Burglars can no longer pick the lock or copy the key from a locksmith’s records — a genuine security win. But now, if you lose the finger (figuratively — say, an injury or a broken sensor), you need a real, well-designed backup plan to get back into your own house, because there is no spare key to keep under the mat anymore.
Common trade-off Keycloak admins must actually decide on
| Decision | Stricter Option | More Convenient Option |
|---|---|---|
| Attestation requirement | Require verified hardware from an approved vendor list | Accept “none” attestation, trusting any authenticator |
| User verification | Require PIN/biometric every time (“required”) | Accept simple presence-touch only (“discouraged”) |
| Credential type | Cross-platform keys only (USB/NFC), harder to lose silently | Platform authenticators allowed, more convenient day to day |
| Fallback method | No fallback — WebAuthn only | Password or recovery code kept as backup |
6Security
Origin binding — the core phishing defense
Every WebAuthn credential is cryptographically tied to a specific Relying Party ID, essentially Keycloak’s domain name. When a browser calls the WebAuthn API, the browser itself — not Keycloak, not the user, not any JavaScript on the page — enforces that the credential can only be used on that exact domain. If an attacker builds a pixel-perfect fake copy of the Keycloak login page on a different domain, the browser will refuse to release a valid signature for it, because the origin does not match what was recorded at registration. This single mechanism is why WebAuthn defeats classic phishing attacks that easily fool password-based logins.
Context
Keycloak deployments behind reverse proxies or multiple subdomains sometimes end up with a mismatched Relying Party ID configuration, which can silently break WebAuthn logins or, worse, weaken origin binding.
Decision
Set the WebAuthn Policy’s Relying Party ID explicitly to the top-level domain users actually see in their browser bar, and keep it identical across every environment sharing user accounts.
Consequence
Credentials remain portable across subdomains of that root domain while still being unusable on any different domain, preserving phishing resistance without breaking legitimate multi-subdomain setups.
Man-in-the-middle and replay resistance
Because every login uses a brand-new random challenge, a captured signed assertion cannot be replayed later to log in again — the old challenge will simply be rejected as stale. Combined with the requirement that Keycloak be served over HTTPS, this closes off the two classic attack patterns that plague password-based systems: credential replay and network interception.
Attestation — verifying the authenticator is genuine hardware
During registration, Keycloak can optionally demand attestation: a signed certificate, baked into the authenticator by its manufacturer, proving the device is a real, certified piece of hardware rather than software pretending to be one. High-security deployments (banking, government, healthcare) often require attestation and check it against an approved metadata list of certified authenticator models. Lower-stakes consumer applications typically accept “none” attestation for a smoother user experience, trading a small amount of assurance for broader device compatibility.
Treating WebAuthn as automatically making an account “unhackable” and therefore skipping account-recovery hardening. If the recovery path (email reset, support desk override) is weak, an attacker can bypass a perfectly secure WebAuthn credential entirely by attacking the weakest link instead.
Session and token security downstream
It is worth remembering that WebAuthn only secures the login moment itself. Once Keycloak issues an OpenID Connect token to the application, standard token security practices — short expiry times, secure storage, HTTPS everywhere, and proper token revocation — still fully apply. WebAuthn strengthens the front door; it does not replace the need to also secure everything that happens after someone walks through it.
7Monitoring, Logging & Metrics
What Keycloak logs by default
Keycloak’s built-in event system records both user-facing events (like a successful or failed login) and admin events (like a configuration change). For WebAuthn, relevant event types include credential registration, credential removal, and both successful and failed WebAuthn login attempts. These events can be streamed to external systems for long-term storage and alerting, since Keycloak’s own event store is meant for short-term operational visibility rather than permanent audit trails.
Metrics worth tracking operationally
WebAuthn adoption rate
Percentage of active users with at least one registered WebAuthn credential — tracks rollout progress against a passwordless goal.
Failed assertion rate
A sudden spike can indicate a browser compatibility regression, a misconfigured Relying Party ID after a domain change, or active probing by an attacker.
Counter anomaly rate
How often Keycloak rejects a login due to a non-increasing sign-counter — a strong signal of credential cloning attempts.
Credential removal frequency
Unexpectedly high removal counts, especially outside normal support-desk activity, can flag account takeover attempts where an attacker strips a victim’s real credentials.
Where Keycloak’s own metrics come from
Keycloak exposes a Prometheus-compatible metrics endpoint (when the metrics feature is enabled), which reports server-level health such as request latency and thread pool usage. WebAuthn-specific business metrics, however, are typically not exposed as ready-made Prometheus counters out of the box; most production teams build these themselves by consuming Keycloak’s event stream (via a listener sent to Kafka, a SIEM, or a logging pipeline) and deriving adoption and failure metrics from the raw events.
A practical dashboard pattern
Many teams build a simple three-panel dashboard: a trend line of daily WebAuthn logins versus password logins (showing adoption over time), a bar chart of failed-versus-successful WebAuthn attempts per day (showing health), and an alert rule that fires whenever counter-anomaly rejections exceed a small baseline threshold in an hour (showing possible cloning attacks in progress).
8Design Patterns & Anti-patterns
Proven patterns
Step-up authentication
Keep password login as the default entry point for low-risk actions, but insert a WebAuthn check as a required extra step before high-risk actions like changing a payment method or approving a large transfer.
Progressive passwordless rollout
Offer WebAuthn as an optional second factor first, measure adoption, then flip the default authentication flow to passwordless-first once enough users have enrolled a credential.
Conditional flow branching
Use Keycloak’s authentication flow “conditional” executions to show WebAuthn only to users who have already registered a credential, falling back to password entry for everyone else — avoiding a confusing prompt for users with nothing enrolled.
Multiple credential encouragement
Nudge users, right after their first WebAuthn enrollment, to register a second device as backup — mirroring how banks encourage a backup card.
Anti-patterns to avoid
Anti-pattern
- Making WebAuthn the sole login method with no recovery path — a single lost device becomes a permanent lockout
- Accepting “none” attestation for a high-security application without any other compensating control
- Ignoring the sign-counter entirely, silently disabling Keycloak’s built-in cloning detection
- Copy-pasting the same Relying Party ID across genuinely unrelated domains, unintentionally letting a credential from one system work on another
Instead, do this
- Always pair WebAuthn with a clearly defined, monitored account-recovery flow
- Match attestation strictness to the actual sensitivity of what’s being protected
- Leave counter checking enabled unless you have a specific, documented reason (like fully synced passkeys) to relax it
- Scope the Relying Party ID to exactly the domain boundary that should share credentials — no more, no less
9Best Practices & Common Mistakes
Best practices
Pilot before you mandate
Roll WebAuthn out to a small, technically comfortable user group first, gather feedback on friction points, then widen the rollout.
Write plain-language enrollment instructions
Most support burden comes from users not understanding what a “security key” prompt actually wants from them — clear, screenshot-based guidance reduces this dramatically.
Require at least two enrolled credentials for critical accounts
Treat a single authenticator the way you’d treat a single house key — fine for convenience, risky as your only copy.
Test across real browsers and devices
WebAuthn behavior differs subtly between Chrome, Safari, and Firefox, and between platform and cross-platform authenticators — test the actual matrix your users will use.
Keep the WebAuthn Policy under version control
Realm export/import or infrastructure-as-code tooling should capture the WebAuthn Policy settings, so a policy change is reviewable and reversible like any other configuration change.
Common mistakes
Enabling WebAuthn only in the “Browser” authentication flow and forgetting that other flows (like the direct grant flow used by some mobile apps) do not support it at all, leading to a confusing gap in security coverage across an organization’s different applications.
Assuming every employee has a device with a fingerprint sensor or camera. Without a supported fallback (like distributing inexpensive USB security keys), a mandatory WebAuthn policy can accidentally exclude a portion of the workforce.
Not communicating that WebAuthn credentials do not automatically transfer to a replacement device unless the platform’s own passkey-sync feature is being used — users who assume it “just moves” to their new phone can be caught off guard.
10Real-world & Industry Examples
Consumer tech giants
Google, Apple, and Microsoft each let users sign in with passkeys built on WebAuthn, letting a face scan or fingerprint replace the account password across billions of devices.
Banking and finance
Financial institutions running Keycloak commonly use WebAuthn as a mandatory step-up factor for high-risk actions such as wire transfers, layering it on top of, rather than instead of, existing authentication.
Healthcare portals
Patient and clinician portals use WebAuthn to satisfy strict regulatory demands for strong authentication while reducing the password-reset burden on hospital IT help desks.
Enterprise workforce identity
Companies standardizing on Keycloak for employee single sign-on issue hardware security keys to staff and enforce WebAuthn as a phishing-resistant replacement for SMS-based one-time codes, which are known to be interceptable.
A representative rollout story
A mid-sized software company running Keycloak for its customer-facing SaaS product first added WebAuthn as an optional second factor alongside passwords. After watching adoption climb over several months and seeing password-related support tickets fall sharply, the team enabled a conditional authentication flow that offers passwordless login to any user with an enrolled credential, while keeping password-plus-email-verification as the fallback for everyone else — achieving a gradual, low-risk migration rather than a disruptive flag-day switch.
11FAQ
12Summary and Key Takeaways
Key Takeaways
- WebAuthn replaces passwords with public-key cryptography, verified through a fingerprint, face scan, or security key, and Keycloak acts as the Relying Party that checks these signatures.
- The private key never leaves the user’s device — Keycloac only ever stores a public key and verifies signed proofs, so a database breach cannot expose usable credentials.
- Origin binding is what makes WebAuthn phishing-resistant: a credential simply will not work on any domain other than the one it was registered against.
- Keycloak supports WebAuthn in both second-factor mode (alongside a password) and fully passwordless mode (discoverable credentials with no typed username).
- The sign-counter is Keycloak’s built-in defense against cloned credentials, though it needs sensible handling for synced passkeys that legitimately don’t increment it.
- Attestation policy should scale with the sensitivity of what’s being protected — strict for banking and healthcare, relaxed for lower-risk consumer use.
- A successful rollout always pairs WebAuthn with a well-designed recovery path and encourages users to register more than one credential.
- WebAuthn secures the login moment; standard token and session security practices still matter for everything that happens afterward.