RFC 9101 — JWT-Secured Authorization Request (JAR)
Spec: datatracker.ietf.org/doc/html/rfc9101Status: Full
RFC 9101 (formerly OpenID Connect Core §6) lets a client pack the authorization request into a signed JWT — the Request Object — instead of sending parameters as plain query strings. This protects the request from tampering in transit and lets a client be authenticated at /authorize rather than only at /token.
Two delivery modes are supported:
request=<JWT>— the JWT is sent inline as a parameter (§6.1).request_uri=<URL>— the JWT is hosted at a URL the OP fetches (§6.2).
WARNING
Earlier AuthHero versions decoded the request JWT without verifying its signature. Any caller could forge claims and have them merged into the authorization request. This page describes the post-fix behavior; that hole is now closed.
How verification works
request JWTs are signature-verified against the client's keys before any claim is applied to the authorization request. request_uri URLs are first fetched (with the SSRF guard described below) and the body runs through the same verifier.
Supported algorithms
| Family | Algorithms | Verified against |
|---|---|---|
| Asymmetric | RS256, RS384, RS512, ES256, ES384, ES512 | Client's registration_metadata.jwks (inline) or client_metadata.jwks_uri (fetched) |
| Symmetric | HS256, HS384, HS512 | Client's stored client_secret |
alg=none is rejected.
Claim validation
The verifier enforces:
iss— must equalclient_idwhen present.aud— must match the OP issuer.exp— validated with 30 s leeway when present.nbf— validated with 30 s leeway when present.
Sending both request and request_uri is rejected with HTTP 400 per the spec.
SSRF guard for request_uri
request_uri is a server-side fetch that the client controls, so it's exposed to SSRF. AuthHero applies these defaults:
https://only —http://URLs are rejected.- No
localhost/127.0.0.0/8/ link-local / private IPv4 ranges. - No private IPv6 ranges (loopback, link-local, ULA).
- 5-second timeout on the fetch.
- 64 KiB body cap — larger bodies are truncated and rejected.
For local development and tests, set ALLOW_PRIVATE_OUTBOUND_FETCH: true on the env binding to relax this guard (allows http://, localhost, and private IPs).
Discovery
/.well-known/openid-configuration advertises:
{
"request_parameter_supported": true,
"request_uri_parameter_supported": true,
"request_object_signing_alg_values_supported": [
"RS256", "RS384", "RS512",
"ES256", "ES384", "ES512",
"HS256", "HS384", "HS512"
]
}Partial / not yet implemented
request_uripre-registration — the spec allows an OP to require clients to pre-register theirrequest_urivalues; AuthHero currently accepts any URL that passes the SSRF guard.- Encrypted request objects (JWE) — only signed JWTs are accepted.
require_signed_request_objectper-client flag — there's no client-level setting yet to require request objects on every authorize call.
Related AuthHero documentation
- OpenID Connect Core — §6 request objects
- RFC 7523 — Client Assertion — uses the same JWT signature verifier on the token endpoint
- Conformance Testing — exercised by
oidcc-request-uri-unsigned,oidcc-unsigned-request-object-supported-correctly-or-rejected-as-unsupported,oidcc-ensure-request-object-with-redirect-uri