Passkey options for a challenge

.md

What a passkey answer to a sign-in challenge has to be signed over.

POST/v1/auth/token/two-factor/passkey-options

A passkey answer has to be signed over a challenge this API issued, so ask for one before showing the system sheet. Send the challenge from the first step and nothing else: who is signing in and which passkeys they have are read from it.

Only passkeys registered through an app are listed. A passkey somebody made on their firm's website is bound to that domain, and an app can neither see it nor ask for it.

Request

curl https://api.proppertrading.com/v1/auth/token/two-factor/passkey-options \
  -H "Content-Type: application/json" \
  -d '{
    "challenge": "a14ea608e89261062f4e90792701ef2a7c5ad1188c8537108efd788d1390ce03"
  }'
FieldTypeDescription
challengestringFrom the sign-in response. Required

Response

The publicKey half of a WebAuthn request, ready to hand to the platform. Field names are WebAuthn's, not ours.

{
    "data": {
        "object": "passkey_request_options",
        "challenge": "3q2-7_8",
        "timeout": 60000,
        "rpId": "proppertrading.com",
        "userVerification": "required",
        "allowCredentials": [{ "id": "AQIDBA", "type": "public-key" }]
    },
    "meta": { "request_id": "req_01kz4bkr1aj1gv63d8fv3133ey" }
}

The challenge inside these options is spent by the next answer, right or wrong. Ask again rather than reusing them.

rpId is ours and stays ours whichever firm the account belongs to. The system sheet on the phone names it, which is the trade this design makes.

Errors

StatusCodeMeaning
401expired_two_factor_challengeThe sign-in challenge is gone, or the account has no passkey an app can use
429rate_limit_exceededTwenty attempts per ten minutes per address, shared with the answer itself
422validation_failedNo challenge, or a malformed one

One reason, two causes

An expired challenge and an account without an app passkey answer the same. From outside there is one thing to do about either: start the sign-in again.