Begin WebAuthn factor enrollment
/v1/identity/auth/mfa/webauthn/enroll/optionsAuthentication
- Bearer Token
AuthorizationJWT access token
Code samples
curl -X POST "https://api.canopy.dev/v1/identity/auth/mfa/webauthn/enroll/options" \ -H "Authorization: Bearer $CANOPY_TOKEN"
const response = await fetch("https://api.canopy.dev/v1/identity/auth/mfa/webauthn/enroll/options", {
method: "POST",
headers: {
"Authorization": "Bearer $CANOPY_TOKEN"
},
});
const data = await response.json();import requests
response = requests.post(
"https://api.canopy.dev/v1/identity/auth/mfa/webauthn/enroll/options",
headers={
"Authorization": "Bearer $CANOPY_TOKEN"
},
)
data = response.json()package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://api.canopy.dev/v1/identity/auth/mfa/webauthn/enroll/options", nil)
req.Header.Set("Authorization", "Bearer $CANOPY_TOKEN")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
200 Generates `PublicKeyCredentialCreationOptions` for `navigator.credentials.create()` and a sealed 5-min enrollment_token carrying the WebAuthn challenge nonce. Browser passes the options to the platform authenticator; the resulting attestation goes back to /verify.
{
"enrollment_token": "string",
"options": {}
}application/json
enrollment_token *stringOpaque short-lived (5 min) sealed token carrying the WebAuthn challenge nonce. Must be returned to /mfa/webauthn/enroll/verify exactly.
options *any object`PublicKeyCredentialCreationOptions` JSON to pass to `navigator.credentials.create()`. Shape per the WebAuthn Level 2 spec; key fields: `rp`, `user`, `challenge`, `pubKeyCredParams`, `excludeCredentials`, `authenticatorSelection`.
401 Invalid or expired token
403 This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)