Refresh and revoke OAuth tokens.
Network operations are deadline-bound and are never retried because a timeout
can leave the remote outcome unknown. Refresh-token rotation is available
through refresh/4, which uses AttestoClient.RefreshCoordinator to prevent
concurrent reuse for the same application record.
Returned tokens are not persisted by this library. Applications must perform any compare-and-swap update and choose their own token/session retention policy.
Summary
Functions
Exchange an OID4VCI pre-authorized code for an access token
(urn:ietf:params:oauth:grant-type:pre-authorized_code,
OpenID4VCI 1.0 Final §6.1/§6.2) - the wallet-holder token step
ahead of AttestoClient.Wallet.request_credential/3.
Refresh a token set through a single-flight coordinator.
Revoke a token according to RFC 7009.
Functions
@spec exchange_pre_authorized_code( String.t(), keyword() ) :: {:ok, AttestoClient.TokenSet.t()} | {:error, term()}
Exchange an OID4VCI pre-authorized code for an access token
(urn:ietf:params:oauth:grant-type:pre-authorized_code,
OpenID4VCI 1.0 Final §6.1/§6.2) - the wallet-holder token step
ahead of AttestoClient.Wallet.request_credential/3.
Required option: :token_endpoint. Private-key JWT authentication also
uses :issuer from trusted discovery when supplied. An omitted issuer
retains the deprecated endpoint-audience fallback in 2.x. :client_id may
be omitted only with client_auth: :none, as permitted for anonymous
pre-authorized-code flows; authenticated methods still require it.
:client_auth and :req_options otherwise behave as for refresh/4.
:alg, :kid, and :now configure DPoP proofs when :dpop is supplied. Pass
:tx_code when the offer's grant carried a tx_code object, i.e. the end
user must key in the transaction code the issuer displayed out of band.
Returns {:ok, token_set}; the ID Token, if any, is returned unverified
since OID4VCI defines no binding claims for it here.
@spec refresh(GenServer.server(), term(), AttestoClient.TokenSet.t(), keyword()) :: {:ok, AttestoClient.RefreshResult.t()} | {:error, term()}
Refresh a token set through a single-flight coordinator.
Required options are :token_endpoint, :issuer, :client_id, and the
:subject from the previously verified ID Token; :client_auth and
:req_options match
AttestoClient.AuthorizationCode.callback/3. The issuer is validated before
the request so an ID Token returned with a rotated refresh token can always
be verified rather than losing the rotation result after the response.
:client_auth also accepts
{:private_key_jwt, jwk, assertion_opts} for an explicitly registered
assertion algorithm, key id, audience, lifetime, time, or JWT id.
A prior DPoP token set requires :dpop signing material before any network
request. Persisted tokens.dpop_jkt must match that key; a missing or changed
key is rejected locally. A requested or prior DPoP token cannot accept a
Bearer response. Shared results are also checked against each caller's key
before adoption. Legacy token sets without a thumbprint require a key, but
their historical key continuity cannot be checked; a successful DPoP response
records the supplied key for subsequent refreshes.
:alg, :kid, and :now configure each DPoP proof and are retained across
the one permitted nonce retry.
The locally retained tokens.id_token_alg selects the ID Token verification
algorithm. An explicit :id_token_alg must match it; mismatches fail before
HTTP. The algorithm survives refreshes even when the response omits an ID
Token, and shared results must match each caller's policy. Legacy token sets
without this field use the explicit option or the existing default (PS256 for
FAPI, RS256 otherwise), then retain that selection for subsequent refreshes.
Revoke a token according to RFC 7009.
A successful 2xx response is :ok, including when the server did not know
the token. Required options: :revocation_endpoint, :client_id; optional
:token_type_hint, :client_auth, :req_options, and :timeout.
With private_key_jwt, pass :issuer from trusted discovery, or an explicit
registered audience in the assertion options for a legacy server. Omitting
both retains the deprecated endpoint-audience fallback in 2.x.