Verification policy for signed authorization request objects (JAR, RFC 9101).
Policy expressed as data the caller passes to
Attesto.AuthorizationRequest.validate/2, which threads it into
Attesto.RequestObject.verify/3. The default %Policy{} is the generic
OpenID Connect §6.1 / RFC 9101 baseline (a signed request object is verified,
but nbf/exp/typ are not required). The FAPI 2.0 Message Signing §5.3.1
profile is the named fapi_message_signing/0 constructor - profile data, not
a feature flag and not a backwards-compatibility shim.
Summary
Functions
The FAPI 2.0 Message Signing §5.3.1 profile for signed request objects
The generic OpenID Connect §6.1 / RFC 9101 baseline: a signed request object
is verified, but nbf/exp/typ are not required. Equivalent to %Policy{}.
Whether this policy requires the authorization request to carry a signed
request object (FAPI 2.0 Message Signing §5.3.1). When true, a request that
presents no request object is rejected rather than processed from its plain
parameters.
Flatten the policy to Attesto.RequestObject.verify/3 options, dropping
optional nil claim policies and the non-verification presence fields
([:require_request_object]). Algorithm and enforcement values remain
present, including malformed nil values, so verification fails closed.
Boolean false remains
present, allowing a generic non-FAPI policy to opt out of the FAPI key gate
explicitly.
Types
@type t() :: %Attesto.RequestObject.Policy{ accepted_algs: [Attesto.SigningAlg.alg()] | nil, accepted_typ: [String.t() | nil] | nil, enforce_fapi_alg_policy: boolean(), max_lifetime_seconds: pos_integer() | nil, max_nbf_age_seconds: pos_integer() | nil, require_exp: boolean(), require_nbf: boolean(), require_request_object: boolean() }
Functions
@spec fapi_message_signing() :: t()
The FAPI 2.0 Message Signing §5.3.1 profile for signed request objects:
- a signed request object is REQUIRED - an authorization request that carries none is rejected (FAPI 2.0 Message Signing §5.3.1, which mandates that clients send the request as a signed JWT);
nbfREQUIRED, no more than 60 minutes in the past;expREQUIRED, no more than 60 minutes afternbf;- JOSE header
typ, when present, must be"oauth-authz-req+jwt", but is NOT required.
accepted_algs retains the default (Attesto.SigningAlg.fapi_algs/0:
PS256, ES256, legacy EdDSA over
Ed25519, and explicit Ed25519). enforce_fapi_alg_policy is set explicitly
so a caller can narrow accepted_algs without disabling the profile's RSA
modulus and Edwards-curve checks.
Note on typ: §5.3.1's "shall accept that typ" requires an OP to accept the
oauth-authz-req+jwt type when a client sends it - it does not license
requiring it, and RFC 9101 §4 makes typ only RECOMMENDED. The FAPI 2.0
Message Signing conformance suite signs its request objects with no typ
header at all, so an OP that mandates typ rejects every conformant request
and fails certification. accepted_typ: ["oauth-authz-req+jwt", nil] therefore
keeps the RFC 9101 §10.8 explicit-typing defence when a typ is present
(a wrong type is still rejected) while accepting its absence.
@spec generic() :: t()
The generic OpenID Connect §6.1 / RFC 9101 baseline: a signed request object
is verified, but nbf/exp/typ are not required. Equivalent to %Policy{}.
Whether this policy requires the authorization request to carry a signed
request object (FAPI 2.0 Message Signing §5.3.1). When true, a request that
presents no request object is rejected rather than processed from its plain
parameters.
Flatten the policy to Attesto.RequestObject.verify/3 options, dropping
optional nil claim policies and the non-verification presence fields
([:require_request_object]). Algorithm and enforcement values remain
present, including malformed nil values, so verification fails closed.
Boolean false remains
present, allowing a generic non-FAPI policy to opt out of the FAPI key gate
explicitly.