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.
- Retain the expected issuer, mode, state, PKCE verifier, nonce and expiry in the application's original transaction.
- 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. - Require
event.originto equal the expected provider origin,event.sourceto equal that exact window, and the message'sissand state to match the transaction. Reject malformed objects and conflicting result fields. - 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.
- 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.