# `Attesto.Plug.Authenticate`
[🔗](https://github.com/XukuLLC/attesto/blob/v0.13.0/lib/attesto/plug/authenticate.ex#L2)

Authenticate a protected-resource request: verify the access token and,
for a DPoP-bound or mTLS-bound token, the sender-constraint proof.

A thin wrapper over the pure verifiers (`Attesto.Token`, `Attesto.DPoP`,
`Attesto.MTLS`). It does the HTTP-specific work - parsing the
`Authorization` and `DPoP` headers, building the `htu`, computing the
client-certificate thumbprint via a host callback, wiring the replay
and nonce checks - then delegates every decision to the engine and
assigns the verified claims onto the conn.

## Options

  * `:config` (required) - an `Attesto.Config` or a zero-arity function
    returning one.
  * `:replay_check` - the DPoP `:replay_check` callback
    (`(jti, ttl) -> :ok | {:error, :replay}`), e.g.
    `&Attesto.DPoP.ReplayCache.check_and_record/2`. **Required for DPoP**:
    without it, RFC 9449 §11.1 replay rejection is off and a captured
    proof can be replayed within the `iat` window. This plug therefore
    fails closed - a DPoP request is rejected (401 `invalid_dpop_proof`,
    `replay_check_unconfigured`) unless `:replay_check` is wired, so an
    unprotected DPoP endpoint cannot silently ship. Bearer/mTLS requests
    are unaffected. A host that knowingly accepts unprotected DPoP sets
    `dpop_replay_unprotected_acknowledged?: true` to opt out.
  * `:dpop_replay_unprotected_acknowledged?` - set to `true` to allow
    DPoP requests through WITHOUT `:replay_check`, accepting that
    captured proofs are replayable. Off by default (fail closed).
  * `:nonce_check` - the DPoP `:nonce_check` callback
    (`(nonce | nil) -> :ok | {:error, :use_dpop_nonce}`).
  * `:nonce_issue` - a zero-arity function returning a fresh DPoP nonce
    for the `use_dpop_nonce` challenge (required if `:nonce_check` is
    set), e.g. `&Attesto.DPoP.NonceStore.ETS.issue/0`.
  * `:cert_der` - `(conn -> der_binary | nil)`; the DER of the client
    certificate the TLS layer authenticated. TLS termination varies, so
    the host supplies it. When it returns a certificate, its RFC 8705
    thumbprint is handed to `Attesto.Token.verify/3`.
  * `:htu` - `(conn -> https_uri_string)` overriding how the request URI
    (without query/fragment) is built; default uses `conn` directly,
    which requires the scheme/host to reflect the external request
    (configure your proxy-forwarding rewrite).
  * `:credential_from_conn` - optional fallback
    `(conn -> {:ok, :bearer | :dpop, token} | :missing)`. Use this for
    host-owned credential channels such as first-party cookies. The
    standard `Authorization` header remains authoritative when present;
    this callback is consulted only when no usable header credential is
    present.
  * `:bearer_methods` - standard RFC 6750 Bearer-token presentation
    methods this resource server accepts. Allowed values are `:header` /
    `"header"` (RFC 6750 §2.1 `Authorization: Bearer`) and `:body` /
    `"body"` (RFC 6750 §2.2 form-body `access_token`). Defaults to
    `[:header]`. Add `:body` only when the protected-resource metadata
    advertises body support and the deployment accepts the logging,
    caching, retry, and replay risks of credentials in request bodies.
    The URI-query method is intentionally unsupported. This setting does
    not disable `Authorization: DPoP`, mTLS binding, or a host-owned
    `:credential_from_conn` fallback.
  * `:claims_key` - the `conn.assigns` key the verified claims are put
    under (default `:attesto_claims`).
  * `:send_error`, `:www_authenticate`, `:no_store` - optional transport
    hooks forwarded to `Attesto.Plug.OAuthError` so a host can keep its
    own JSON error envelope while Attesto owns the RFC status/challenge
    semantics.
  * `:resource_metadata` - the URL of this resource's protected-resource
    metadata (RFC 9728), advertised as a `resource_metadata` auth-param on
    every 401 `WWW-Authenticate` challenge (RFC 9728 §5.1) so a client that
    is refused can discover the authorization server.

    plug Attesto.Plug.Authenticate,
      config: &MyApp.Attesto.config/0,
      replay_check: &MyApp.DPoPReplay.check_and_record/2,
      cert_der: &MyApp.TLS.client_cert_der/1

---

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