AshAuthentication.Strategy.WebAuthn.Actions (ash_authentication v5.0.0-rc.8)

Copy Markdown View Source

Core action implementations for the WebAuthn strategy.

Wraps the wax_ library for FIDO2 ceremony handling and coordinates with Ash to persist users and credentials.

Summary

Functions

Add a new WebAuthn credential to an existing user.

Delete a credential, refusing to delete the last one.

List all credentials for a user.

Register a new user with a WebAuthn credential.

Generate a registration challenge.

Sign in a user with a WebAuthn credential.

Sign in a user using a short-lived sign-in token issued by a successful WebAuthn ceremony.

Verify that the caller can produce a valid WebAuthn assertion using one of actor's registered credentials.

Functions

add_credential(strategy, params, opts \\ [])

@spec add_credential(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.record()} | {:error, any()}

Add a new WebAuthn credential to an existing user.

This is used when a user wants to register an additional security key or passkey. Unlike register/3, this does NOT create a new user - it attaches a credential to an existing one.

Params should include:

  • "attestation_object" - Base64url-encoded attestation object from the browser
  • "client_data_json" - Base64url-encoded client data JSON from the browser
  • "label" - Optional human-readable label for the credential

Options must include:

  • challenge: - The Wax.Challenge used for this ceremony
  • user: - The existing user to attach the credential to

authentication_challenge(strategy, allow_credentials, tenant, opts \\ [])

@spec authentication_challenge(
  AshAuthentication.Strategy.WebAuthn.t(),
  list(),
  any(),
  keyword()
) ::
  {:ok, Wax.Challenge.t()}

Generate an authentication challenge.

Pass origin: "..." in opts to override the strategy's configured origin.

delete_credential(strategy, user, credential_id, opts)

@spec delete_credential(
  AshAuthentication.Strategy.WebAuthn.t(),
  Ash.Resource.record(),
  any(),
  keyword()
) :: :ok | {:error, any()}

Delete a credential, refusing to delete the last one.

list_credentials(strategy, user, opts)

@spec list_credentials(
  AshAuthentication.Strategy.WebAuthn.t(),
  Ash.Resource.record(),
  keyword()
) ::
  {:ok, [Ash.Resource.record()]} | {:error, any()}

List all credentials for a user.

register(strategy, params, opts \\ [])

@spec register(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.record()} | {:error, any()}

Register a new user with a WebAuthn credential.

registration_challenge(strategy, tenant, opts \\ [])

@spec registration_challenge(
  AshAuthentication.Strategy.WebAuthn.t(),
  any(),
  keyword()
) ::
  {:ok, Wax.Challenge.t()}

Generate a registration challenge.

Pass origin: "..." in opts to override the strategy's configured origin (e.g. with the request's actual origin when serving from a Plug or LiveView).

sign_in(strategy, params, opts \\ [])

@spec sign_in(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.record()} | {:error, any()}

Sign in a user with a WebAuthn credential.

sign_in_with_token(strategy, params, opts \\ [])

@spec sign_in_with_token(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.record()} | {:error, any()}

Sign in a user using a short-lived sign-in token issued by a successful WebAuthn ceremony.

The token is verified, the matching user is loaded, and a fresh authentication token is placed in user.__metadata__.token for use as a session credential.

update_credential_label(strategy, credential_id, new_label, opts)

@spec update_credential_label(
  AshAuthentication.Strategy.WebAuthn.t(),
  any(),
  String.t(),
  keyword()
) ::
  {:ok, Ash.Resource.record()} | {:error, any()}

Update the label of a credential.

verify(strategy, params, opts \\ [])

@spec verify(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.record()} | {:error, any()}

Verify that the caller can produce a valid WebAuthn assertion using one of actor's registered credentials.

Used as a second factor on top of another primary credential. On success, stamps :webauthn_verified_at onto the user metadata and (if tokens are enabled) issues a fresh JWT carrying the same value as a webauthn_verified_at claim — both are picked up by RequireWebauthn on subsequent requests.