Lockspire. Protocol. AccessTokenSigner
(lockspire v1.4.0)
Copy Markdown
Shared access-token issuance for all Lockspire grant paths.
Owns the single RFC 9068 at+jwt signing site, the opaque-token delegate, and
the one-place format decision (per-client override -> server default -> :jwt).
Format resolution
The effective access-token format is resolved in exactly one place
(resolve_format/2):
- a per-client
access_token_formatof:jwtor:opaquewins; - otherwise (
nil) the server-wideServerPolicy.access_token_formatread viarequest.opts[:server_policy_store]is used; - otherwise it falls back to
:jwt.
Audience derivation
The four grant paths (authorization-code, refresh, device-code, CIBA) emit a
LIST aud: the requested resource(s) when present, otherwise [client_id].
The RFC 8693 token-exchange path keeps a BARE-STRING aud == client_id via
issue_exchange/4, preserving the historical exchange wire shape.
Security
The signing alg/kid are taken ONLY from the active signing key — never from
client-controlled input — and none is never emitted. On a missing or invalid
key the error path logs inspect(reason) only: no key material reaches logs.
Summary
Functions
Issue an access token for a standard grant path.
Issue a signed at+jwt access token for the RFC 8693 token-exchange path.
Types
@type result() :: {:ok, String.t(), String.t()} | {:error, Lockspire.Protocol.TokenExchange.Error.t()}
Functions
@spec issue(Lockspire.Domain.Token.t(), Lockspire.Domain.Client.t(), map()) :: result()
Issue an access token for a standard grant path.
Resolves the effective format and returns {:ok, raw, hash} where
hash == Lockspire.Security.Policy.hash_token(raw), or a 500
:token_signing_failed error when the :jwt branch cannot sign.
The :jwt branch emits a LIST aud derived from token.audience.
@spec issue_exchange( Lockspire.Domain.Token.t(), Lockspire.Domain.Client.t(), map(), map() ) :: result()
Issue a signed at+jwt access token for the RFC 8693 token-exchange path.
Always :jwt. Emits a BARE-STRING aud == client.client_id (the exchange
carve-out) and merges custom_claims over the base claims after dropping the
restricted claims iss sub aud exp iat jti client_id.