Passkeys & WebAuthn

The Web Authentication API (WebAuthn) is a specification that allows web applications on supported browsers to authenticate a user via authenticator types such as built-in device biometrics (e.g. facial recognition on mobile and fingerprint readers on desktop) or secure hardware keys (e.g. YubiKeys). While WebAuthn has many benefits, developers need to understand the API to implement it securely. Stytch's WebAuthn product simplifies the process by abstracting the implementation details of WebAuthn for developers to make it as quick as possible to implement securely.

Configuring App Site Association

In order for your application to support Passkeys, you must associate your app with a domain that you control.

For iOS, follow the instructions here, specifically as they relate to the webcredentials configuration.

For Android, follow the instructions here.

Methods

The Stytch SDK can be used to create new WebAuthn registrations for users and authenticate existing WebAuthn registrations.

To call these methods, WebAuthn must be enabled in the SDK Configuration page of the Stytch dashboard.

Register

Wraps Stytch's register_start and register WebAuthn endpoints, the Credential Manager API on Android and the CredentialProvider API on iOS. Call this method to prompt the user to enroll a new WebAuthn factor and save the factor in Stytch.

Call webauthn.register inside an event callback triggered by a user gesture.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.

Note: If a user has enrolled another MFA method, this method will require MFA. See the Multi-factor authentication section for more details.


Method parameters


domain*string

is_passkeyboolean

session_duration_minutesint
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react-native';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytchClient.webauthn.register({
      domain: 'example.com',
      is_passkey: true,
    });
  }, [stytchClient]);

  return <button onClick={trigger}>Create WebAuthn Registration</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
    "webauthn_registration_id": "webauthn-registration-test-5c44cc6a-8af7-48d6-8da7-ea821342f5a6"
  }

Authenticate

Wraps Stytch's authenticate_start and authenticate WebAuthn endpoints, the Credential Manager API on Android and the CredentialProvider API on iOS. Call this method to authenticate a user using an existing WebAuthn registration in Stytch.

Call webauthn.authenticate inside an event callback triggered by a user gesture.

You can listen for successful user updates anywhere in the codebase with the stytch.user.onChange() method or useStytchUser() hook if you are using React.


Method parameters


domain*string

is_passkeyboolean

session_duration_minutesint
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react-native';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytchClient.webauthn.authenticate({
      domain: 'example.com',
      is_passkey: true,
      session_duration_minutes: 60,
    });
  }, [stytchClient]);

  return <button onClick={trigger}>Authenticate WebAuthn Registration</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "session": null
    "session_jwt": "",
    "session_token": "",
    "user": {...},
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
    "webauthn_registration_id": "webauthn-registration-test-5c44cc6a-8af7-48d6-8da7-ea821342f5a6",
  }

Update

Allows a WebAuthn registration to be updated with a different name.


Method parameters


webauthn_registration_id*string

name*string
import React, { useCallback } from 'react';
import { useStytch } from '@stytch/react-native';

export const Login = () => {
  const stytchClient = useStytch();

  const trigger = useCallback(() => {
    stytch.webauthn.update({
        webauthn_registration_id: 'webauthn_registration_id',
        name: 'WebAuthn Registration Name'
    });
  }, [stytchClient]);

  return <button onClick={trigger}>Update WebAuthn Registration</button>;
};

RESPONSE

200
{
    "status_code": 200,
    "request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
    "user_id": "user-test-16d9ba61-97a1-4ba4-9720-b03761dc50c6",
    "webauthn_registration": {
      "webauthn_registration_id": "webauthn-registration-test-5c44cc6a-8af7-48d6-8da7-ea821342f5a6",
      "domain": "example.com",
      "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
      "authenticator_type": "platform",
      "verified": true,
      "name": "Google Passkey"
    }
  }