A successful Face ID, fingerprint, or system credential prompt does not prove that a passkey deployment is secure. The real trust boundary is the server: was the challenge single-use, do the RP ID and origin match, does the signature verify against a bound public key, which account owns the credential, and how does the user recover after losing every available credential?

A passkey is an identity-system change, not a new button beside the password field.

Model accounts and credentials separately

Allow one account to own multiple WebAuthn credentials. For each credential, store its credential ID, public key, internal account ID, creation and last-used times, revocation state, and the AAGUID, backup state, and signature-counter observations needed by the risk model. The private key remains inside the authenticator or credential provider and never reaches the server.

The WebAuthn user handle is an opaque byte sequence of at most 64 bytes. It must not contain an email address, phone number, or username. Use a stable random internal identifier so that changing a login name does not require replacing a passkey and credential metadata does not disclose personal information.

Enforce global uniqueness for credential IDs. Account deletion, merging, and tenant migration all need explicit credential-ownership behavior. A device label is useful management metadata, but it is not a security identity.

Registration begins with a server challenge

Require a trusted session before creating a passkey, with recent reauthentication for high-value accounts. The server generates a high-entropy random challenge, binds it to the account, registration intent, RP ID, and a short expiry, and permits one consumption. The client must not generate challenges or reuse a failed challenge indefinitely.

Creation options include a stable RP ID, opaque user ID, supported algorithms, user-verification policy, and excludeCredentials containing existing credential IDs. The RP ID is normally a service domain. Once production credentials depend on it, changing domains casually can strand those credentials.

After the client returns a credential, use a maintained FIDO/WebAuthn server library to validate at least the ceremony type and challenge in clientDataJSON, an allowed origin, the RP ID hash, user-presence and required user-verification flags, algorithm and public-key encoding, and that the credential ID is not attached to another account. Only then consume the challenge and store the public key in one transaction.

Most consumer services can request attestation: none, avoiding device-identification and privacy complexity. A regulated service that needs attestation must define trust roots, metadata refresh, unknown-model behavior, and certificate-revocation handling. Merely storing an attestation object is not attestation verification.

Authentication verifies every binding

Sign-in starts with another server-issued, single-use challenge. Discoverable credentials allow an empty allowCredentials list so that the platform can offer accounts for the RP without a username-first screen. When the assertion arrives, verify the challenge, ceremony type, allowed origin, RP ID hash, user presence, required user verification, credential-to-account mapping, and signature with the stored public key.

After successful verification, atomically update last-used and risk observations, rotate the session identifier, and issue the application session. The assertion is not a permanent API token.

The signature counter can be a clone or anomaly signal, but synchronized passkeys do not necessarily behave like one-device authenticators. If a counter does not advance, combine that observation with backup state, device change, and account behavior. Do not lock every legitimate device based on one counter alone.

External failures should resist account enumeration. Unknown credentials, invalid signatures, and missing accounts can return similar public errors. Internal events should contain a nonsensitive category and trace identifier, never the full challenge, assertion, or user handle.

Native apps must prove their domain relationship

For a website, iOS app, and Android app to share an account credential, keep the RP ID consistent and configure each platform’s secure association. An Apple app declares a webcredentials Associated Domain, while the website serves an apple-app-site-association file matching the app identifier over HTTPS. Without that relationship, the app cannot use passkeys for the service.

Android uses Digital Asset Links to associate the website with an application package and signing certificate, then exposes passkeys through Credential Manager. The server must allow the Android origins for real production signing certificates; debug certificates do not belong in the production allowlist. Before a signing, domain, or CDN change, verify the relationship from a released build rather than trusting a local request.

Treat association files as authentication infrastructure. Monitor HTTPS availability, content type, caching, and accidental redirects, and give changes a rollback plan. One bad deployment can prevent the entire native population from discovering existing credentials.

Management and recovery are part of authentication

Account settings should list recognizable credential names, provider or device hints, creation time, and last-used time, with actions to add, rename, and revoke. Warn before removing the last passkey if no other sign-in method remains. Adding or deleting a credential, changing recovery, and signing out other sessions require recent strong authentication and a user notification.

Synchronized passkeys reduce device-replacement friction, but they do not make credential loss impossible. A user can lose the credential-provider account, switch ecosystems, or rely only on a device-bound security key. Encourage a second independent credential and provide risk-assessed recovery codes, trusted-device confirmation, or manual identity proofing.

Recovery must not be dramatically weaker than the passkey. If one easily compromised mailbox can reset a high-value account, phishing resistance protects only the happy path. After recovery, revoke lost credentials and high-risk sessions, notify established channels, and consider a cooling-off period for security-sensitive actions.

Migrate progressively

Passkeys can coexist with passwords or federated sign-in while adoption grows. After a successful legacy sign-in, offer passkey creation. Use the platform’s conditional interface so existing passkeys appear naturally in the account-entry flow instead of requiring users to understand a new term first.

Measure registration success, subsequent passkey use, cancellation reason, recovery rate, and support cases by platform. Lower password prominence only after major devices, accessibility needs, and recovery journeys are covered. A user who cannot use biometrics should still be able to complete user verification with a device PIN or security key.

Test attacker and loss paths

Automated tests should cover replayed, expired, and mismatched challenges; wrong origins and RP IDs; missing presence or verification flags; modified signatures; unknown, duplicate, and revoked credentials; concurrent use; unsupported algorithms; account merge and deletion. Production probes should also check Apple and Android association files.

Run end-to-end tests on real devices and representative credential providers: new-account registration, discoverable sign-in, cross-device use, a second credential, revocation, lost device, and full recovery. Record the stage and error category without violating the same redaction rules applied to production authentication data.

Before launch, confirm that challenges are random, short-lived, intent-bound, and single-use; the server validates origin, RP ID, flags, and signature; user handles contain no personal data; accounts support multiple manageable credentials; iOS and Android associations work with production signing; recovery does not weaken authentication; legacy methods recede by measured evidence; and attacker plus device-loss tests pass on real hardware.

Passkeys derive their value from a complete chain of trust. The platform protects the private key, domain association scopes credential use, the server verifies every ceremony, the account system manages multiple credentials, and recovery preserves identity after device loss. A demo-level implementation in any link can turn a passwordless experience into a new account-takeover path.