# `Attesto.RequestObject.Policy`
[🔗](https://github.com/XukuLLC/attesto/blob/v0.13.0/lib/attesto/request_object/policy.ex#L1)

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.

# `t`

```elixir
@type t() :: %Attesto.RequestObject.Policy{
  accepted_algs: [Attesto.SigningAlg.alg()] | nil,
  accepted_typ: [String.t() | nil] | nil,
  max_lifetime_seconds: pos_integer() | nil,
  max_nbf_age_seconds: pos_integer() | nil,
  require_exp: boolean(),
  require_nbf: boolean(),
  require_request_object: boolean()
}
```

# `fapi_message_signing`

```elixir
@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);
  * `nbf` REQUIRED, no more than 60 minutes in the past;
  * `exp` REQUIRED, no more than 60 minutes after `nbf`;
  * JOSE header `typ`, when present, must be `"oauth-authz-req+jwt"`, but is
    NOT required.

`accepted_algs` is left `nil` to inherit `Attesto.RequestObject.verify/3`'s
default (`Attesto.SigningAlg.fapi_algs/0`: PS256, ES256, EdDSA).

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.

# `generic`

```elixir
@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{}`.

# `require_request_object?`

```elixir
@spec require_request_object?(t()) :: boolean()
```

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.

# `to_verify_opts`

```elixir
@spec to_verify_opts(t()) :: keyword()
```

Flatten the policy to `Attesto.RequestObject.verify/3` options, dropping `nil`
values so `verify/3` keeps its own defaults (notably `accepted_algs`, which
defaults to `Attesto.SigningAlg.fapi_algs/0`) and the non-verification
presence fields (`[:require_request_object]`).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
