Prompt and applicable context
The product already supports username/password login and conditional get for passkey sign-in. You want to use WebAuthn Level 3 conditional create after a high-trust login, suggesting a passkey without interrupting the flow. Explain browser capability detection, creation gates, server validation, privacy boundaries, and rollback.
This focuses on the Web platform and authentication UX. Browser API support does not mean the device has a usable authenticator; creation still requires user consent and server verification.
What the interviewer evaluates
- Whether you distinguish conditional create, conditional get, and explicit button-based creation.
- Whether you connect capability, policy, account state, and cross-device synchronization into clear gates.
- Whether you prevent duplicate credentials, account misbinding, credential-existence leaks, and blocked password login.
- Whether you can canary and withdraw the feature instead of enabling a new API everywhere.
A strong answer treats conditional create as an enhancement: unsupported, canceled, or timed-out attempts leave the primary flow unchanged, while the server still verifies the challenge, origin, RP ID, and account binding.
Clarifying questions before answering
- Is the target every signed-in user, or only users with verified email, MFA, or a recent high-risk reauthentication?
- Are multi-device synchronized passkeys allowed? That changes recovery and revocation requirements.
- Can the page already have a pending
credentials.create()request? Concurrent requests make prompts unpredictable. - When conditional create is unavailable, should you show an explicit “Create a passkey” button or hide the feature?
30-second answer framework
“I would detect conditional-create capability, then combine account state, recent authentication strength, and a server feature flag before attempting it. The client starts at most one request at an explicit user-approved moment and cancels duplicates with AbortController; unsupported, canceled, or timed-out attempts return to the original flow. The server binds a one-time challenge to the user, origin, RP ID, and expiry, and stores the credential only after verification. During the canary I would track creation success, cancellation, duplicate credentials, password fallback, and recovery tickets. An incident disables the flag; existing credentials can still be used or revoked separately.”
Step-by-step deep answer
1. Separate the two conditional interactions
Conditional get lets a user choose an existing passkey while entering an account; conditional create suggests registering a new credential in the form context. Both depend on browser and authenticator capability, so checking only for the PublicKeyCredential object is insufficient.
Capability detection decides whether to try, not whether to authorize. The server should still bind registration to the currently authenticated user and record the creation source and policy version.
2. Define creation gates
Require all of: the browser reports conditional-create capability; the user recently completed sufficient authentication; the account is not in recovery, merge, or high-risk change; and a server flag enables the tenant and traffic slice. On a new device, explain the benefit and let the user continue instead of creating on page load.
3. Prevent duplicates and races
Allow one create request per page session. Cancel the previous request before starting another and cancel it when the component unmounts. A server challenge is single-use, credential IDs have a unique constraint, and duplicate submissions return an idempotent result rather than creating another row.
capability -> policy gate -> one challenge -> user consent
| | |
fallback feature flag server verify -> persist4. Validate the registration completely
The server verifies challenge, origin, RP ID, signature, user handle, attestation policy, and credential ID. Never trust a client-side “created” result. If device attestation is not required, choose a simpler attestation policy and state the privacy and risk trade-off.
5. Handle synchronization and recovery
A synchronized passkey may appear after the user changes devices, but synchronization is not account recovery. Provide a credential list, single-credential revocation, and a recovery path for users who lose every device. Do not reveal passkey existence to unauthenticated requests.
6. Canary with useful telemetry
Enable by browser, platform, tenant, and risk level. Record capability detection, prompt display, consent, verification failures, cancellation/timeouts, duplicate credentials, password fallback, and support tickets. Separate “unsupported” from “user declined”; otherwise you cannot tell whether to improve copy or disable the feature.
7. Roll back without breaking accounts
Use a remote flag to stop new creation attempts while retaining existing passkey login. Never delete credentials as part of a release rollback; revocation is an account operation. Keep a bounded compatibility window for older challenge versions and rerun browser and authenticator tests when behavior changes.
High-quality sample answer
I would ship conditional create as a reversible enhancement. The client detects capability, then checks account state, recent authentication strength, and a feature flag; one request per page is enforced and AbortController cancels duplicates. The server creates a single-use challenge and verifies challenge, origin, RP ID, signature, and credential ID before persistence. Unsupported, canceled, or timed-out attempts return to password login and never become login failures. I would canary by platform and risk while tracking capability, consent, verification errors, duplicate credentials, fallback, and recovery tickets. Disabling the flag stops new creation but keeps existing passkeys and revocation available.
Common mistakes
- Mistake → checking only whether
PublicKeyCredentialexists → the object does not prove conditional create or an authenticator is available; fix: use capability detection and keep a fallback. - Mistake → silently calling create on page load → the user did not consent and duplicate prompts become likely; fix: trigger at an explicit high-trust moment and let the user continue.
- Mistake → trusting a client-side success result → challenge, origin, or account binding may be unverified; fix: complete registration verification on the server.
- Mistake → deleting new credentials during rollback → a release rollback becomes account destruction; fix: disable new creation and manage revocation separately.
Follow-up questions and responses
Should you prompt every day after a user declines?
No. Record a local cooldown and policy version. Ask again only when account risk, device, or product conditions materially change; declining must not affect password login.
What if the same account has two rows with the same credential ID?
Make credential ID unique, make registration idempotent, and record the source. If duplicates already exist, freeze new writes and merge or review by user and credential ID; never silently overwrite one.
Capability is supported but success suddenly drops. What do you inspect first?
Slice by browser version, platform, authenticator, and error code to separate cancellation, timeout, policy rejection, and server verification failure. Pause the affected flag cohort, keep password and existing passkey login, fix the cause, and revalidate with a small cohort.