# `AshAuthentication.Strategy.WebAuthn.Actions`
[🔗](https://github.com/team-alembic/ash_authentication/blob/main/lib/ash_authentication/strategies/webauthn/actions.ex#L5)

Core action implementations for the WebAuthn strategy.

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

# `add_credential`

```elixir
@spec add_credential(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.Record.t()} | {: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`

```elixir
@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`

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

Delete a credential, refusing to delete the last one.

# `list_credentials`

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

List all credentials for a user.

# `register`

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

Register a new user with a WebAuthn credential.

# `registration_challenge`

```elixir
@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`

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

Sign in a user with a WebAuthn credential.

# `sign_in_with_token`

```elixir
@spec sign_in_with_token(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.Record.t()} | {: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`

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

Update the label of a credential.

# `verify`

```elixir
@spec verify(AshAuthentication.Strategy.WebAuthn.t(), map(), keyword()) ::
  {:ok, Ash.Resource.Record.t()} | {: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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
