# `Attesto.DPoP.Proof`
[🔗](https://github.com/XukuLLC/attesto/blob/v2.6.1/lib/attesto/dpop/proof.ex#L1)

Builds signed DPoP proof JWTs as defined by RFC 9449 section 4.

The proof binds a public key to one HTTP method and target URI. Query and
fragment components are excluded from the `htu` claim, and an access token
can be bound through the `ath` claim for protected-resource requests.

This module is the client-side counterpart to `Attesto.DPoP.verify_proof/2`.
It accepts a private `%JOSE.JWK{}` or JWK map and embeds only its public
members in the protected header.

# `build_opt`

```elixir
@type build_opt() ::
  {:access_token, String.t()}
  | {:nonce, String.t()}
  | {:alg, String.t()}
  | {:kid, String.t()}
  | {:now, DateTime.t() | non_neg_integer()}
  | {:jti, String.t()}
```

# `error`

```elixir
@type error() ::
  :invalid_key
  | :invalid_kid
  | :invalid_htm
  | :invalid_htu
  | :invalid_access_token
  | :invalid_nonce
  | :invalid_time
  | :invalid_jti
  | :unsupported_alg
  | :unsupported_key
  | {:signing_failed, String.t()}
```

# `jwk`

```elixir
@type jwk() :: JOSE.JWK.t() | map()
```

# `build`

```elixir
@spec build(jwk(), String.t(), String.t(), [build_opt()]) ::
  {:ok, String.t()} | {:error, error()}
```

Builds a signed DPoP proof for `htm` and `htu`.

The target must be an absolute HTTPS URI without userinfo. Its query and
fragment are stripped before the `htu` claim is signed. Use `:access_token`
to add `ath`, and `:nonce` to echo a server-issued DPoP nonce.

`:alg` must be an asymmetric algorithm accepted by `Attesto.DPoP`; when it
is omitted, the key's declared `alg` is used before falling back to key-type
inference. An explicit algorithm cannot override a conflicting key
declaration. The optional `:kid` follows the same precedence rule: an
explicit value wins, otherwise the key's declared `kid` is used.

---

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