Authorization response modes

Choose how M7 delivers an authorization-code result to your application. response_type=code selects the result type; response_mode selects its delivery. Every mode below carries a code or an authorization error. Access, refresh and ID tokens are obtained afterward from the token endpoint.

Register a list, request one mode

The M7 registration extension response_modes is an allowlist. An application may register several modes, then send exactly one case-sensitive response_mode on each authorization request. It must be both registered for that client and advertised by live discovery.

Omitting the request parameter selects query; it does not select the first registered mode. If the client allows only form_post, it must explicitly request form_post. An unsupported or disallowed mode returns a local invalid_request; M7 does not fall back to another delivery method.

For example, this JSON is the response-mode portion of a registration request:

{
  "response_modes": ["query", "form_post.jwt", "web_message.opener"],
  "authorization_signed_response_alg": "RS256"
}

Use API User client management to change an existing client. Registration omission or [] selects ["query"]. An omitted management update preserves an existing nonempty list; authorized reads and writes fill an empty stored list with query.

Send the selected mode with the ordinary authorization parameters, in the body submitted to PAR, or inside the signed Request Object for JAR. PAR and JAR preserve the selected mode with the original transaction; an outer browser parameter cannot replace it. JAR Request Objects at /par remain unsupported.

Delivery table

Requested mode Delivery Response location
query Browser redirect Ordinary fields in the callback query
form_post Automatically submitted form, POST, application/x-www-form-urlencoded Ordinary fields in the form body
fragment Browser redirect Ordinary fields in the callback fragment after #
query.jwt Browser redirect One query field, response, containing signed JARM
form_post.jwt Automatically submitted form POST One body field, response, containing signed JARM
fragment.jwt Browser redirect One fragment field, response, containing signed JARM
jwt Default JARM delivery for code flow Same transport as query.jwt
web_message.opener Browser postMessage Response object to the opening window
web_message.parent Browser postMessage Response object to the embedding parent
web_message Browser postMessage Opener when present; otherwise the embedding parent

Every callback uses the validated registered HTTPS redirect_uri. Keep it free of fragments and reserved response parameter names. Safe existing query parameters are preserved. The same selected mode delivers success and safely returnable errors, including cancellation. See callback outcomes for the field and error contract.

Form and fragment callbacks

For form POST, accept the expected form content type at the registered callback and validate the original transaction. A cross-site form POST may omit a SameSite=Lax session cookie. Your callback architecture must recover the original transaction safely; missing cookies never justify skipping state validation. The current M7 Web SDK uses a same-origin browser relay before continuing its existing callback processing.

A fragment is never sent to the callback server. Browser code must read it, remove it from the visible URL, and pass it to the application's trusted callback processor. Handle the result only through the transport saved for the transaction. Reject mixed query/body/fragment inputs and duplicate protected fields. Keep callback and relay pages non-cacheable and free of third-party scripts and analytics.

Signed authorization responses: JARM

M7 implements signed JARM. The four JARM modes carry one compact JWS in response. Its contents are readable: signing provides integrity, not encryption. JARM is a response envelope, not an access token, ID token or client assertion.

authorization_signed_response_alg selects exactly RS256 or RS512 and defaults to RS256. Dynamic Registration returns the effective value. For an existing client, set it with API User's set_knobs; omission preserves the current setting, while null, an empty string or default removes the override and restores the RS256 default. This policy is independent of ID-token signing, signed UserInfo, JAR and client authentication. Selecting an algorithm does not itself enable a JARM response mode.

JARM field M7 contract
Protected alg and kid Registered RS256/RS512 algorithm and provider signing-key identifier
iss Exact authorization-server issuer, https://sso.user.m7.org
aud Exact public OAuth client_id, not a resource API audience
iat, exp Numeric issuance and expiry; M7 issues a five-minute envelope
state Original transaction state when available
code Successful authorization only
error and optional error fields Authorization failure only, including M7 error_reason and optional trace_id

Validate the signature using the expected provider's discovered JWKS, exact kid, and the algorithm saved for this client. Do not obtain keys from URLs inside an untrusted JWT. Require the exact issuer and client audience, valid time claims, matching single-use state, and exactly one terminal result. Only then may the application use the code or process the error. Reject unsigned, tampered, expired, replayed, wrong-client and mixed plain/JARM responses. Never accept unsigned outer fields as replacements for JWT claims.

authorization_signing_alg_values_supported advertises the two JARM algorithms. authorization_encrypted_response_alg and authorization_encrypted_response_enc are unsupported and rejected by Dynamic Registration. Authorization-response encryption remains deferred.

Web Message: popup and iframe

M7's three Web Message modes follow the Web Message response-mode draft. This is a draft extension, not a claim of finalized OAuth standardization. The provider sends a JavaScript object with string values: the ordinary code or error fields, state, and iss=https://sso.user.m7.org. These modes do not wrap the result in a JARM JWT.

The provider uses the validated full redirect URI as the postMessage target; the browser derives the receiving origin. The redirect remains a registered security boundary even though the provider does not navigate the secondary window to it.

  1. Retain the expected issuer, mode, state, PKCE verifier, nonce and expiry in the application's original transaction.
  2. Install the message listener before opening the popup or loading the frame. Open a popup from a user gesture and retain its exact window reference; for an iframe, retain its contentWindow.
  3. Require event.origin to equal the expected provider origin, event.source to equal that exact window, and the message's iss and state to match the transaction. Reject malformed objects and conflicting result fields.
  4. Accept only one matching result, remove the listener, and close the popup or remove the frame. Continue code exchange in the original application context; an error must not start token exchange.
  5. On blocked/closed windows or expired transactions, offer a fresh sign-in. Do not bypass the window, origin or state checks to recover.

Explicit opener and parent modes use only their named receiver. Generic web_message prefers an opener; it uses a parent only when no opener exists. A missing, self or closed receiver fails; a closed opener does not cause a silent switch to a parent. Popup settings that sever the opener relationship, including noopener or incompatible cross-origin isolation, prevent delivery.

Iframe prerequisites and current limits

The embedding origin needs provider approval in the applicable CSP frame-ancestors policy, and the application must permit the provider in its own frame-src. Registering web_message.parent does not grant permission to frame M7. The current provider allowance is restricted to approved test origins; coordinate an exact-origin allowance before using an iframe on another site.

Cross-site cookie restrictions can prevent remembered-account reuse. The live iframe checks completed fresh password sign-in and cancellation; they did not establish silent or remembered-session sign-in. MFA, email sign-in, upstream federation and consent denial were not exercised by those iframe checks and may need additional framing and browser acceptance. Use a top-level or popup flow when the required hosted step cannot operate inside the frame.

M7 Web SDK configuration

Response-mode-aware Web SDK source accepts M7_RESPONSE_MODE with any of the ten names. For JARM, M7_AUTHORIZATION_SIGNED_RESPONSE_ALG must match the client's RS256/RS512 policy. M7_AUTH_USE_PAR selects PAR or direct authorization. The generic launcher offers popup and embedded sign-in; explicit parent/opener modes offer only their matching presentation.

These capabilities were tested from the updated source package. Existing immutable SDK downloads are not changed by this provider update; use a package that explicitly includes the required callback support.

Device Authorization and client_credentials do not use an authorization callback, so response modes do not change their token delivery.