Specification: Financial-grade API: JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)
JARM moves every authorization response parameter — success or error — into a single signed response JWT, so a client can tell a response this server produced from one an attacker assembled on the redirect.
Response Modes
-
query.jwt(§2.1) — code-flow responses, signed JWT in the query string -
fragment.jwt(§2.1) — responses carrying anid_token, signed JWT in the fragment -
jwtshorthand (§2.3.4) — resolves toquery.jwtorfragment.jwtper the response type, mirroring how plainquery/fragmentalready resolve -
response_modepersisted with the authorization conversation — a response built after/authorizeaccepted the parameter honors the mode the request actually started under, rather than re-deriving it from state that may have changed - Signed error responses (§4.3) — a rejected or failed authorization also returns a signed
responseJWT, not only a successful one
Response JWT
-
iss,aud,expclaims (§2.1) — issuer identifier, the requesting client, and a 5-minute expiry - Every response parameter carried as a claim,
stateincluded;issis not also sent as a bare parameter alongside the signed copy - Signed with the tenant’s own active signing key — §2.2 leaves the algorithm choice to the server
-
authorization_signed_response_algper-client override (§2.2 names this a “MAY”) — not implemented; every client under a tenant is signed with that tenant’s one active key, and a client resolves the algorithm actually used fromauthorization_signing_alg_values_supportedin discovery, or from the JWT’s ownalg/kidheader, rather than by registering a preference - Encrypted response (nested JWE, §2.3) — not supported; JARM responses are signed only, never encrypted
Authorization Server Metadata
-
authorization_signing_alg_values_supported(§4) — derived from the deployment’s actual signable keys, so it cannot drift away from what a response is ever signed with -
response_modes_supportedadvertisesjwt,query.jwt,fragment.jwtalongside the plainquery/fragment
State Protection (s_hash)
s_hash is not part of JARM itself; it comes from FAPI 1.0 Advanced §5.2.2, which requires it wherever an ID Token is returned as a detached signature alongside a state value. It is documented here because both were built together — JARM protects the redirect, s_hash protects the state inside the token riding alongside it.
-
s_hashclaim included in the ID Token whenever the authorization request carried astatevalue (FAPI 1.0 Advanced §5.2.2-4) — left-most half of the hash ofstate, using the same digest as the ID Token’s own signing algorithm, the identical construction OIDC Core §3.3.2.11 uses forc_hash - Computed on both the hybrid-flow authorization response and the redeemed conversation’s ID Token