Start a WebAuthn Passkey Assertion or Authentication

This API is used to start a WebAuthn authentication ceremony by providing some details about the current user and the new passkey. The response is a JSON object which is suitable to be passed to the WebAuthn JavaScript API navigator.credentials.get() function and includes a one-time challenge unique to the current ceremony. This same API is used to start a WebAuthn assertion that validates a passkey signature without authenticating the user.

Request#

API Key Authentication
Start a WebAuthn Authentication Ceremony and Retrieve Passkey Request Options
POST/api/webauthn/start
OpenAPI Spec

Request Headers#

X-FusionAuth-TenantIdStringoptional

The unique Id of the tenant used to scope this API request.

The tenant Id is not required on this request even when more than one tenant has been configured because the tenant can be identified based upon the request parameters or it is otherwise not required.

Specify a tenant Id on this request when you want to ensure the request is scoped to a specific tenant. The tenant Id may be provided through this header or by using a tenant locked API key to achieve the same result.

See Making an API request using a Tenant Id for additional information.

Request Body#

applicationIdUUIDrequired

The Id for the application to which the user wishes to authenticate.

credentialIdUUIDoptional

The unique database Id for one of a user's passkeys. When provided, the authentication ceremony will use this passkey. Otherwise, any of a user's passkeys that meet the user verification requirement will be eligible for the authentication ceremony.

loginIdString

The login identifier of the authenticating user. The login identifier can be one of the following (see loginIdTypes for information on which of these identifiers will be used):

  • Email address
  • Phone number (if phoneNumber is included in loginIdTypes)
  • Username
Required if userId is not present. If both fields are provided in the request body, the userId will be utilized.
loginIdTypesArray<String>optionalDefaults to [email, username]Available since 1.59.0

The identity types that FusionAuth will compare the loginId to. Can be one or more of the following:

  • email
  • phoneNumber
  • username
The order is significant. If ["email", "username"] is supplied with a loginId value of terry@example.com, then a user with terry@example.com as their email address will match first before any user with terry@example.com as their username.
stateObjectoptional

An optional object that will be returned un-modified when you complete the WebAuthn authentication request. This may be useful to return the user to a particular state once they complete the authentication.

userIdUUIDoptional

The unique Id of the authenticating user.

This field is marked optional, but you must provide either the loginId or the userId to complete this API. If both fields are provided in the request body, the userId will be utilized.

workflowStringrequired

The WebAuthn workflow for the current authentication ceremony. The workflow value changes the options object generated by this API. The options object is built to be passed to the WebAuthn JavaScript API call. The possible values are:

  • bootstrap - The user is authenticating using a WebAuthn passkey after providing their email, username, or other information to identify themselves.
  • reauthentication - The user is reauthenticating on a device they have previously authenticated from.

Example Request JSON

{
  "applicationId": "82b24314-95f6-4393-b3da-72c341185244",
  "userId": "703fe2d2-2d39-4cb7-b76d-0b9918ed2457",
  "workflow": "reauthentication"
}

Response#

Response Codes
CodeDescription
200The request was successful. The response will contain a JSON body.
400The request was invalid and/or malformed. The response will contain an Errors JSON Object with the specific errors. This status will also be returned if a paid FusionAuth license is required and is not present.
401You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See Authentication.
500There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty.
503The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body.

Response Body#

The response body contains options to be passed to the WebAuthn JavaScript API. The options.challenge and options.allowCredentials[x].id fields must be converted to ArrayBuffers for the navigator.credentials.get() request. See WebAuthn JavaScript API Binary Format for details.

optionsObject

The WebAuthn public key credential request options. This object is passed to the WebAuthn JavaScript API to generate an assertion using an available passkey.

options.allowCredentialsArray

An array containing identifying information for passkeys that are allowed to complete this authentication ceremony, ordered from most to least preferred.

options.allowCredentials[x].idString

The credential Id generated by the authenticator as a base64url-encoded string. This value is used to locate an authenticator that can complete the ceremony.

See Converting base64url-encoded String to ArrayBuffer for details on converting these values for the WebAuthn JavaScript API call.

options.allowCredentials[x].transportsArray<String>

A list of transport types supported by the authenticator that generated the passkey. This value is used as a hint to help identify authenticators containing one of the options.allowCredentials.

FusionAuth treats the list of transports as strings to maximize authenticator compatibility. These values are used as hints during WebAuthn ceremonies and missing, extra, or unexpected values should not cause a ceremony to fail. Some common values are:

  • internal - the authenticator is integrated with the client device
  • usb - the authenticator can be contacted over USB
  • nfc - the authenticator can be contacted over Near Field Communication (NFC)
  • ble - the authenticator can be contacted over Bluetooth Smart (Bluetooth Low Energy, or BLE)
  • cable - "cloud-assisted" BLE. This transport is used for Android devices acting as an authenticator connected to the computer over Bluetooth
  • hybrid - replacement for the cable transport
options.allowCredentials[x].typeString

The credential type the current passkey refers to. The only value supported by WebAuthn is public-key.

options.challengeString

This field contains a base64url-encoded string that acts as a one-time challenge for the ceremony. This makes WebAuthn resistant to certain kinds of replay attacks.

See Converting base64url-encoded String to ArrayBuffer for details on converting this value for the WebAuthn JavaScript API call.

options.rpIdString

The Relying Party Id for this authentication ceremony. Passkeys can only be used to authenticate on sites with the same Relying Party Id with which the passkeys were registered.

If this value is null or omitted, the WebAuthn JavaScript API will use the browser origin as the Relying Party Id.

options.timeoutLong

The number of milliseconds the Relying Party is willing to wait for the ceremony to complete. This value is treated as a hint and may be overridden by the client. This is an unsigned value.

options.userVerificationString

The Relying Party's user verification requirement. Eligible authenticators will be filtered according to this preference. Possible values are:

  • discouraged - The Relying Party does not want user verification to be used.
  • preferred - The Relying Party prefers that user verification is used if available but will not fail the ceremony if it is not provided.
  • required - The Relying Party requires user verification for the operation.

Example Response JSON

{
  "options": {
    "allowCredentials": [
      {
        "id": "HdN9wqP9mqOonacmiM2gIjASFYg",
        "transports": [
          "internal"
        ],
        "type": "public-key"
      }
    ],
    "challenge": "fdnW2u1_Nk9_FY2SprU4mPs0NgBTbo9tOO5Q9EvO1Oc",
    "rpId": "piedpiper.com",
    "timeout": 180000,
    "userVerification": "required"
  }
}