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) - anAttesto.Configor a zero-arity function returning one.:replay_check- the DPoP:replay_checkcallback ((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 theiatwindow. This plug therefore fails closed - a DPoP request is rejected (401invalid_dpop_proof,replay_check_unconfigured) unless:replay_checkis wired, so an unprotected DPoP endpoint cannot silently ship. Bearer/mTLS requests are unaffected. A host that knowingly accepts unprotected DPoP setsdpop_replay_unprotected_acknowledged?: trueto opt out.:dpop_replay_unprotected_acknowledged?- set totrueto allow DPoP requests through WITHOUT:replay_check, accepting that captured proofs are replayable. Off by default (fail closed).:nonce_check- the DPoP:nonce_checkcallback ((nonce | nil) -> :ok | {:error, :use_dpop_nonce}).:nonce_issue- a zero-arity function returning a fresh DPoP nonce for theuse_dpop_noncechallenge (required if:nonce_checkis 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 toAttesto.Token.verify/3.:htu-(conn -> https_uri_string)overriding how the request URI (without query/fragment) is built; default usesconndirectly, which requires the scheme/host to reflect the external request (configure your proxy-forwarding rewrite).:claims_key- theconn.assignskey the verified claims are put under (default:attesto_claims).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