OpenID Connect Authorization Code flow with S256 PKCE.
start/2 validates discovery metadata, creates high-entropy state, nonce, and
PKCE values, stores the transaction with a finite lifetime, and returns the
authorization URL. callback/3 atomically consumes state, exchanges the code
exactly once, and verifies the ID Token against the stored issuer, client,
nonce, configured algorithm, and returned access token.
Transactions are also bound to an opaque application-supplied browser-session value, preventing a response initiated in one user agent from being used in another. The store protects protocol correlation only. Applications remain responsible for deciding whether verified claims authorize a user, creating or retaining a session, and persisting rotated tokens.
Summary
Functions
Consume an authorization response and complete the code exchange.
Begin an authorization transaction.
Types
@type store() :: AttestoClient.AuthorizationTransaction.Store.store()
Functions
@spec callback(store(), map(), keyword()) :: {:ok, %{tokens: AttestoClient.TokenSet.t(), id_token_claims: map()}} | {:error, term()}
Consume an authorization response and complete the code exchange.
params is the string-keyed callback parameter map. State is consumed before
any token request, so replay and concurrent duplicate callbacks fail.
:browser_binding is required and must equal the opaque value supplied to
start/2; a mismatch consumes state and fails before token exchange. The
client authentication option is forwarded as :client_auth; supported forms
are :none, {:client_secret_basic, secret},
{:client_secret_post, secret}, and {:private_key_jwt, jwk}.
The three-element form {:private_key_jwt, jwk, assertion_opts} accepts
:alg, :kid, :audience, :lifetime, :now, and :jti for registrations
whose client assertion differs from the defaults; :client_id is always
pinned to the stored transaction.
A timeout leaves the remote outcome unknown and the transaction consumed; do not retry an authorization code.
@spec start( store(), keyword() ) :: {:ok, %{url: String.t(), state: String.t(), expires_in: pos_integer()}} | {:error, term()}
Begin an authorization transaction.
Required options are :issuer, :client_id, :redirect_uri, and an opaque
:browser_binding retained in the initiating user agent's secure, HttpOnly
application session. The same binding is mandatory at callback. The value is
protocol correlation only; authorization and session policy remain
application-owned.
Discovery is fetched unless :metadata is supplied. :scopes defaults to
["openid"] and must include openid. :id_token_alg defaults to "RS256"
and must match the client's registration and the provider metadata.
Additional request values may be supplied in :authorization_params, but
protocol-bound parameters cannot be overridden.