Begin a WebAuthn-backed step-up ceremony
/v1/identity/auth/mfa/step-up/webauthn/optionsAuthentication
- Bearer Token
AuthorizationJWT access token
Code samples
curl -X POST "https://api.canopy.dev/v1/identity/auth/mfa/step-up/webauthn/options" \ -H "Authorization: Bearer $CANOPY_TOKEN"
const response = await fetch("https://api.canopy.dev/v1/identity/auth/mfa/step-up/webauthn/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/step-up/webauthn/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/step-up/webauthn/options", nil)
req.Header.Set("Authorization", "Bearer $CANOPY_TOKEN")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
200 Generates `PublicKeyCredentialRequestOptions` for the caller's enrolled WebAuthn factors plus a sealed 5-min `transit_token` carrying the cryptographic nonce. Browser passes the options to `navigator.credentials.get()`; the assertion goes back to /verify along with the transit_token.
{
"transit_token": "string",
"options": {}
}application/json
transit_token *stringSealed 5-min token carrying the WebAuthn nonce. Must be returned to /verify exactly.
options *any object`PublicKeyCredentialRequestOptions` for navigator.credentials.get(). Shape per the WebAuthn Level 2 spec.
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)