Lockspire.Protocol.Jar
(lockspire v1.0.0)
Copy Markdown
JWT Secured Authorization Request (JAR) foundation.
Provides unverified decoding, signature verification, and security claims validation of RFC 9101 request objects.
Summary
Functions
Decodes a JWT string without signature verification.
Decrypts a nested JWE request object to return the inner JWS string.
If the input is not a JWE (e.g. it is a 3-part JWS), it returns {:ok, jwt} immediately.
Validates RFC 9101 security claims on a decoded JAR request object.
Verifies the signature of a JAR request object using the client's registered public keys.
Types
@type validate_claims_reason() ::
:invalid_claims_options
| :missing_issuer
| :invalid_issuer
| :missing_audience
| :invalid_audience
| :missing_expiration
| :invalid_expiration
| :expired_token
| :expiration_too_far
| :invalid_not_before
| :invalid_issued_at
Functions
Decodes a JWT string without signature verification.
@spec decrypt(String.t(), [Lockspire.Domain.SigningKey.t()]) :: {:ok, String.t()} | {:error, :decryption_failed}
Decrypts a nested JWE request object to return the inner JWS string.
If the input is not a JWE (e.g. it is a 3-part JWS), it returns {:ok, jwt} immediately.
@spec validate_claims( t(), keyword() ) :: :ok | {:error, validate_claims_reason()}
Validates RFC 9101 security claims on a decoded JAR request object.
Required options:
:expected_client_id(binary) — theissclaim MUST equal this value.:expected_audience(binary) — theaudclaim MUST contain this value.
Optional options:
:now— aDateTime.t()representing the current time forexp/nbf/iatchecks. Defaults toDateTime.utc_now/0.:leeway(non-negative integer, seconds) — clock skew tolerance applied to time-based checks. Defaults to0.:max_age(positive integer, seconds) — caps the time betweennowandexp. When set, returns{:error, :expiration_too_far}ifexp - now > max_age + leeway. When nil/absent, no ceiling is applied (preserves Phase 21 behavior).
Returns :ok on success, or {:error, reason} where reason is one of:
:invalid_claims_options— required options missing or malformed.:missing_issuer/:invalid_issuer—issclaim missing or mismatched.:missing_audience/:invalid_audience—audclaim missing or mismatched.:missing_expiration/:invalid_expiration/:expired_token—expclaim missing, malformed, or in the past.:expiration_too_far—expis farther in the future than:max_age + leewaypermits (RFC 9101 replay-window mitigation, T-22-03).:invalid_not_before—nbfis present but in the future.:invalid_issued_at—iatis present but in the future.
Security: Mitigates T-21-05 (Repudiation) by binding requests to a specific
client via iss, and T-21-06 (Information Disclosure) by ensuring requests
are intended for this AS via aud.
@spec verify_signature(String.t(), Lockspire.Domain.Client.t(), [String.t()]) :: {:ok, t()} | {:error, :invalid_signature | :no_matching_key | :invalid_client_keys | :invalid_typ}
Verifies the signature of a JAR request object using the client's registered public keys.
Returns {:ok, %Jar{}} if the JWT signature is valid and the signing key matches a
key registered for the client.
Returns {:error, reason} where reason is one of:
:invalid_signature— the JWT signature does not verify against the client's keys:no_matching_key— no key could be loaded from the client's JWKS:invalid_client_keys— the client'sjwksfield is missing, not a map, or cannot be parsed as a JWK or JWK Set by JOSE:invalid_typ— the JWT protected header has atypvalue other thanoauth-authz-req+jwtorjwt(case-insensitive). RFC 9101 §10.8 cross-JWT-confusion mitigation (T-22-01).
Security: alg=none is never accepted. Only algorithms in the explicit allow-list are
permitted, mitigating T-21-03 (Spoofing) and T-21-04 (Tampering).