AttestoClient.RequestObject (AttestoClient v0.6.0)

Copy Markdown View Source

Build signed authorization request objects (JAR, RFC 9101), the client-side mirror of Attesto.RequestObject.verify/3.

A request object is a JWT that carries the authorization request parameters as claims, signed with the client's own key, so the authorization server can authenticate and integrity-check the request (RFC 9101; FAPI 2.0 Message Signing §5.3.1 requires it). This builds one; the authorization server (via attesto) verifies it at the PAR or authorization endpoint.

Claims

The caller's authorization parameters (:params - response_type, redirect_uri, scope, state, nonce, code_challenge, …) become top-level claims. The builder adds the request-object envelope, which always wins over :params:

  • iss = the client_id (RFC 9101 §2.1).
  • aud = the authorization server (:audience, its issuer identifier).
  • iat, nbf, exp = issuance / not-before / expiry; FAPI 2.0 Message Signing §5.3.1 requires nbf and exp.
  • jti = a unique identifier.

The JOSE header typ defaults to "oauth-authz-req+jwt" (RFC 9101 §10.8 / FAPI 2.0 Message Signing §5.3.1 explicit typing); it is accepted by attesto's generic policy too, so it is safe for non-FAPI servers and may be overridden with :typ. Signing and :alg/:kid/validation behave as in AttestoClient.ClientAssertion.

Summary

Functions

Build a signed request object, returning {:ok, compact_jws} or {:error, reason}. Fails fast on invalid input (see the error type).

Types

build_opt()

@type build_opt() ::
  {:client_id, String.t()}
  | {:audience, String.t()}
  | {:params, %{optional(String.t()) => term()}}
  | {:typ, String.t()}
  | {:alg, String.t()}
  | {:kid, String.t()}
  | {:lifetime, pos_integer()}
  | {:now, integer()}
  | {:jti, String.t()}

error()

@type error() ::
  :invalid_key
  | :invalid_client_id
  | :invalid_audience
  | :invalid_params
  | :invalid_typ
  | :invalid_lifetime
  | :invalid_time
  | :invalid_jti
  | :unsupported_alg
  | :unsupported_key
  | {:signing_failed, String.t()}

jwk()

@type jwk() :: JOSE.JWK.t() | map()

Functions

build(jwk, opts)

@spec build(jwk(), [build_opt()]) :: {:ok, String.t()} | {:error, error()}

Build a signed request object, returning {:ok, compact_jws} or {:error, reason}. Fails fast on invalid input (see the error type).

jwk is the client's private key. Required options: :client_id, :audience. The authorization parameters go in :params (a string-keyed map, defaulting to %{}). See the module docs for :typ and the envelope claims; :alg, :kid, :lifetime, :now, and :jti behave as in AttestoClient.ClientAssertion.build/2.