Passkey
Registering a WebAuthn passkey — issuing the challenge and submitting the attestation.
A passkey is a phishing-resistant sign-in method: the private key stays in the device's secure element and authentication only presents a signature. Registration is two steps, like every other credential type.
Endpoints
| Method | Path | Purpose | Step-up |
|---|---|---|---|
POST | /v1/auth/credentials/passkey/options | Issue the registration challenge | max_age=300 |
POST | /v1/auth/credentials/passkey | Submit the attestation | None |
Step one: issue the challenge
| Parameter | Type | Required | Notes |
|---|---|---|---|
user_verification | preferred | required | Optional | Defaults to preferred |
{ "success": true, "options": { "challenge": "...", "rp": { "id": "id.example.com" } }, "expires_in": 300 }user_verification: required forces the authenticator to actually check the user (PIN or biometrics) instead of merely confirming "someone tapped it". The preferred default exists for hardware keys without UV capability.
The challenge is kept server-side. Already registered credentials appear in excludeCredentials, so the same device is not registered twice.
Step two: submit the attestation
| Parameter | Type | Required | Notes |
|---|---|---|---|
response | object | ✅ | RegistrationResponseJSON, passed through to the WebAuthn check |
label | string | Optional | Device name, 1–64 chars |
{ "success": true, "credential": { "id": "cred_...", "type": "passkey", "display": "MacBook" } }The challenge is consumed before verification
A failure means going back to step one; the same challenge cannot be retried. This is deliberate: a reusable challenge would let one registration request be replayed onto several devices.
Filling in label is recommended: without it, several passkeys all read the same in the list and the user cannot tell which one to delete.
Related
- Using a passkey to sign in: Verification challenges
- Other credential types: Credential management