Enterprise Passkeys: Architecture, Deployment, and Operational Guide
Prerequisites
- Working knowledge of IAM, SSO, and MFA
- Familiarity with Microsoft Entra ID or Keycloak administration
Steps
Passkeys replace passwords with phishing-resistant FIDO2 credentials bound to user devices and verified with public key cryptography. This guide explains how enterprises design, deploy, and harden passkey authentication across workforce and customer identity platforms.
Overview
Passkeys are FIDO2/WebAuthn credentials that authenticate users with a device-bound or synced private key instead of a reusable password. The server stores only a public key, reducing credential theft, password spraying, and phishing risk.
Enterprises adopt passkeys to improve user experience, meet phishing-resistant MFA requirements, and lower help desk costs from password resets. They are especially effective for workforce SSO, privileged access portals, customer identity journeys, and zero trust access.
Architecture
Core components
- User device and authenticator: Platform authenticators such as Windows Hello, Apple iCloud Keychain, and Android Credential Manager, or roaming security keys.
- Relying Party (RP): The application or identity provider that registers and verifies WebAuthn credentials.
- Identity Provider (IdP): Microsoft Entra ID, Okta, or Ping can broker passkey authentication into SAML or OIDC applications.
- Directory and policy layer: Group-based rollout, device compliance, conditional access, and recovery policy.
- Audit and telemetry: Sign-in logs, authenticator attestation metadata, and SIEM forwarding.
Deployment models
- Workforce via IdP: Preferred for centralized policy and app federation.
- Customer identity in application: Native WebAuthn in the app for low-friction sign-in.
- Hybrid: IdP for workforce and direct WebAuthn for external users.
Data flow
- User starts registration.
- RP requests a challenge from the server.
- Authenticator creates a key pair and returns attestation.
- Server validates attestation and stores the public key and credential ID.
- On login, server sends a challenge.
- Authenticator signs the challenge with the private key.
- Server verifies the signature and user presence or verification flags.
Implementation Guide
1. Enable passkeys in Microsoft Entra ID
az login
az extension add --name microsoft-graph
az rest --method PATCH --url "https://graph.microsoft.com/beta/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/Fido2" --headers 'Content-Type=application/json' --body '{"@odata.type":"#microsoft.graph.fido2AuthenticationMethodConfiguration","isAttestationEnforced":true,"isSelfServiceRegistrationAllowed":true,"keyRestrictions":{"isEnforced":false,"enforcementType":"allow","aaGuids":[]},"state":"enabled"}'
2. Configure a WebAuthn-enabled reverse proxy with Keycloak
Create docker-compose.yml and start Keycloak.
mkdir -p /opt/keycloak-passkeys && cd /opt/keycloak-passkeys
docker compose up -d
3. Create realm and WebAuthn policy
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password 'ChangeMe!'
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh create realms -s realm=corp -s enabled=true
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh update realms/corp -r master -s 'webAuthnPolicyRpEntityName=Corp SSO' -s 'webAuthnPolicySignatureAlgorithms=["ES256","RS256"]' -s 'webAuthnPolicyUserVerificationRequirement=required' -s 'webAuthnPolicyAuthenticatorAttachment=not specified' -s 'webAuthnPolicyRequireResidentKey=no'
4. Register a test user and enforce browser flow
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh create users -r corp -s username=alice -s enabled=true
docker exec -it keycloak /opt/keycloak/bin/kcadm.sh set-password -r corp --username alice --new-password 'TempPass123!'
In the admin console, clone the browser flow and add WebAuthn Passwordless Authenticator after username identification for pilot users.
5. Validate registration and authentication
Use browser developer tools to confirm navigator.credentials.create() and navigator.credentials.get() succeed and that RP ID matches the effective domain.
Code Examples
version: '3.8'
services:
keycloak:
image: quay.io/keycloak/keycloak:25.0.0
container_name: keycloak
command: start-dev
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ChangeMe!
KC_PROXY: edge
KC_HOSTNAME: sso.example.com
ports:
- "8080:8080"
{
"rp": { "name": "Corp Portal", "id": "portal.example.com" },
"user": { "id": "YWxpY2VAZXhhbXBsZS5jb20", "name": "alice@example.com", "displayName": "Alice Admin" },
"challenge": "q1w2e3r4t5y6u7i8o9p0",
"pubKeyCredParams": [
{ "type": "public-key", "alg": -7 },
{ "type": "public-key", "alg": -257 }
],
"authenticatorSelection": { "residentKey": "preferred", "userVerification": "required" },
"timeout": 60000,
"attestation": "direct"
}
from fido2.server import Fido2Server
from fido2.webauthn import PublicKeyCredentialRpEntity
rp = PublicKeyCredentialRpEntity(id="portal.example.com", name="Corp Portal")
server = Fido2Server(rp)
registration_data, state = server.register_begin(
user={"id": b"alice-123", "name": "alice@example.com", "displayName": "Alice Admin"},
user_verification="required"
)
print(registration_data)
Security Hardening
- Require user verification to enforce biometrics or device PIN.
- Prefer attestation enforcement for managed workforce devices where hardware trust matters.
- Restrict registration to compliant devices using conditional access and MDM signals.
- Protect recovery flows; account recovery is often weaker than passkey auth itself.
- Log credential registration, AAGUID, sign count anomalies, and failed assertions to the SIEM.
- Use TLS 1.2+ and HSTS; RP ID must align with the production domain.
Comparison
| Feature | Passkeys | Okta FastPass | Cisco Duo Passwordless |
|---|---|---|---|
| Pricing | Often included in platform/browser ecosystem; IdP licensing may apply | Included with Okta Identity Engine tiers | Requires Duo subscription |
| Deployment | Native WebAuthn/FIDO2 across apps and IdPs | Best in Okta-centric environments | Best in Duo-protected environments |
| Scalability | Internet-scale with standards-based federation | High, tied to Okta tenant design | High, tied to Duo service architecture |
| Security | Phishing-resistant, asymmetric cryptography, device/user verification | Strong phishing resistance with device trust | Strong phishing resistance with push and passwordless factors |
Troubleshooting
Error 1: RP ID mismatch
Log sample:
[webauthn] Registration failed: SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current domain.
Fix: Set RP ID to the exact parent domain, for example example.com or portal.example.com, and ensure reverse proxy headers preserve hostnames.
Error 2: Origin validation failure
Log sample:
2026-04-12 09:14:22,411 WARN [org.keycloak.authentication] (executor-thread-7) WebAuthn authentication failed: Invalid origin https://login.internal.local expected https://sso.example.com
Fix: Correct KC_HOSTNAME, external URL, and TLS termination settings so the browser origin matches server policy.
Error 3: User verification unavailable
Log sample:
fido2.server - ERROR - ValueError: User verification required but authenticator cannot satisfy UV
Fix: Ensure the device has biometrics or PIN configured, or relax policy to preferred for limited pilot groups.
Best Practices
Do
- Start with a pilot group in IT and security teams.
- Keep at least two authenticators per privileged user, for example platform passkey plus FIDO2 security key.
- Integrate sign-in telemetry with Sentinel, Splunk, or Chronicle.
- Document recovery with identity proofing and admin break-glass controls.
Don't
- Do not leave password fallback enabled indefinitely for high-risk apps.
- Do not allow unmanaged devices for privileged passkey registration.
- Do not ignore cross-platform UX differences between synced and device-bound credentials.
- Do not treat passkeys as complete without hardening enrollment and recovery paths.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI