# `Attesto.ClientAssertion`
[🔗](https://github.com/XukuLLC/attesto/blob/v0.13.0/lib/attesto/client_assertion.ex#L1)

`private_key_jwt` client authentication verification (RFC 7523 / OIDC Core).

The host owns client registration and key storage. This module only verifies
a compact client assertion against trusted client JWKs supplied by the host
and checks the standard claims:

  * `iss` and `sub` equal the OAuth `client_id`
  * `aud` contains the expected token endpoint/audience
  * `exp` is in the future
  * `iat`, when present, is not meaningfully in the future
  * `jti` is present for replay tracking by the caller

The JOSE algorithm is resolved from the trusted JWK's `alg` member when
present, otherwise from the key shape. It is never accepted just because the
presented JWT header names it.

# `verify_error`

```elixir
@type verify_error() ::
  :invalid_assertion
  | :invalid_signature
  | :invalid_client_id
  | :invalid_audience
  | :expired
  | :not_yet_valid
  | :missing_jti
  | :unsupported_critical_header
```

# `verify_opts`

```elixir
@type verify_opts() :: [
  now: DateTime.t() | non_neg_integer(),
  max_lifetime: pos_integer(),
  accepted_algs: [Attesto.SigningAlg.alg()]
]
```

# `assertion_type`

```elixir
@spec assertion_type() :: String.t()
```

The required `client_assertion_type` value for `private_key_jwt`.

# `peek_client_id`

```elixir
@spec peek_client_id(String.t()) :: {:ok, String.t()} | {:error, :invalid_assertion}
```

Peek `iss` from an assertion without trusting it.

# `verify`

```elixir
@spec verify(
  String.t(),
  String.t(),
  String.t() | [String.t()],
  map() | [map()] | map(),
  verify_opts()
) ::
  {:ok, map()} | {:error, verify_error()}
```

Verify a client assertion against the client's trusted JWK Set.

`trusted_jwks` may be an RFC 7517 JWK Set (`%{"keys" => [...]}`), a single
public JWK map, or a list of public JWK maps.

Opts:

  * `:accepted_algs` - the JOSE algorithms a candidate trusted key may use.
    Defaults to `SigningAlg.fapi_algs/0` (PS256, ES256, EdDSA), keeping the
    FAPI 2 client-authentication gate. A non-FAPI profile can widen this.

---

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