M7 OAuth 2.0 and OpenID Connect Provider Profile
Status: Release-candidate public contract
Profile version: M7-OIDC-1.0-RC4
Last reviewed: 2026-09-16
This profile defines the interoperable OAuth 2.0 and OpenID Connect behavior that an external M7 client can rely on. It consolidates the choices M7 makes where the underlying standards permit several behaviors. The endpoint guides linked from this page remain the detailed request and response references.
This is a release-candidate profile, not an OpenID certification claim. The independent-library, RFC 8705 mTLS, and scoped JAR interoperability campaigns have passed; the official OpenID conformance-suite run remains pending.
The server supports all 15 asymmetric signing profiles below. Shared issuance and personal Device Authorization/strict-refresh flows passed live algorithm tests; normal browser sign-in and refresh were confirmed by the operator. After deploying the updated Identity SDK, the operator also confirmed Ed25519 browser sign-in and refresh. This does not claim a separate authorization-code campaign for every algorithm or ML-DSA browser-cookie compatibility.
HS256/384/512 client-secret signing additionally passed client credentials, device/strict-refresh and browser login/profile/refresh. See HMAC setup and acceptance boundaries. Both live discovery documents advertise these three algorithms alongside the 15 asymmetric profiles, for 18 total.
HMAC ID tokens are restricted to confidential clients. The User.M7/SSO update
rejecting token_endpoint_auth_method=none with HMAC is implemented and
locally tested; production deployment verification remains pending. The
earlier public-device HMAC test is historical signing evidence, not an
eligible configuration under this policy. See the setup guide above for
errors, existing-client repair and the retained shared-storage boundary.
At 2026-09-15 21:49:24 UTC, both live discovery documents returned identical metadata with all 18 ID-token algorithms. Provider JWKS covered all 15 asymmetric profiles and contained no symmetric material. HMAC discovery is deployed and advertised. Consumers MUST use the live advertisement when selecting automatically; see HMAC and discovery.
All ten authorization response modes and JARM RS256/RS512 signing are deployed and advertised, verified from both discovery documents at 2026-09-15 06:24 UTC. Direct authorization, PAR and cancellation passed live for each mode, including both flexible Web Message presentations. These checks do not extend the certification, encryption or iframe account-reuse claims below.
The key words MUST, MUST NOT, SHOULD, and MAY describe the M7 integration contract. They do not broaden an application's registered grants, scopes, audiences, or ownership.
Profile identity and discovery
| Item | Contract |
|---|---|
| Authorization-server issuer | https://sso.user.m7.org |
| OpenID discovery | https://sso.user.m7.org/.well-known/openid-configuration |
| OAuth authorization-server metadata | https://sso.user.m7.org/.well-known/oauth-authorization-server |
| Subject type | public |
| Authorization response | code; query, form POST, fragment, signed JARM and Web Message modes |
| Profile version | M7-OIDC-1.0-RC4 |
Clients MUST use discovery for endpoint locations and advertised capability sets. This profile defines behavior and constraints that cannot be represented completely in discovery metadata. Automatic negotiation MUST treat an absent advertisement as unavailable. Explicitly configured HMAC clients use the separate shared-secret contract linked above. Account-level two-factor settings have no discovery flag; their hosted behavior is described separately below.
M7 publishes asymmetric signing keys at the discovered jwks_uri. For those profiles, clients MUST select a
key by the signed JWT's exact kid and supported alg, verify the signature,
and then validate the token-class claims. They MUST NOT trust a decoded JWT
without verification.
Issuer rules by token class
| Token or response | Issuer rule |
|---|---|
| New ID token | Exact discovery issuer, https://sso.user.m7.org |
| Migrating ID token | The documented transitional allowlist may also contain legacy id.m7.org |
| Signed UserInfo response | Exact discovery issuer |
| Signed JARM authorization response | Exact discovery issuer; audience is the public OAuth client ID |
| Web Message response | iss equals the exact discovery issuer; browser sender origin and window must also match |
| Current M7 access token | Current token-profile issuer id.m7.org; do not substitute the discovery issuer |
The legacy ID-token issuer is a migration compatibility rule, not a suffix or host-matching rule. New integrations SHOULD use the canonical discovery issuer and MUST reject unrelated issuer values.
Supported integration shapes
| Need | Supported profile |
|---|---|
| Browser, web, SPA, or native user sign-in | Authorization code with PKCE S256 |
| CLI, TV, or input-constrained user sign-in | OAuth Device Authorization Grant |
| Service acting as itself | client_credentials with a confidential client |
| Long-lived user authorization | Rotating refresh-token lineage when refresh_token is registered and granted |
| Back-channel authorization request | Pushed Authorization Requests (PAR) |
| Signed authorization request | Per-client JAR by value or registered HTTPS URI at /authorize |
M7 does not support implicit or hybrid response types. A client MUST use
response_type=code. PKCE is required for authorization-code flow, and the
only accepted method is exact S256; plain is not supported.
The application MUST create high-entropy, single-use state and SHOULD create
a single-use OpenID Connect nonce. It MUST validate callback state and the
requested nonce in the ID token before establishing an application session.
Authorization response delivery
The supported response modes are query, form_post, fragment,
query.jwt, form_post.jwt, fragment.jwt, jwt, web_message.opener,
web_message.parent, and web_message. A client MAY register several through
the M7 response_modes extension, but MUST select one permitted mode per
request. Omission selects query; it does not select the first allowed mode.
An unsupported or disallowed value fails without a fallback transport.
PAR and JAR MUST retain the selected mode in their bound transaction.
Signed JARM MUST use the client's authorization_signed_response_alg, exactly
RS256 or RS512 with RS256 as the default. The client MUST validate signature,
provider issuer, client-ID audience, expiry and single-use state before acting
on the enclosed code or error. JARM is signed, readable and not encrypted.
Its signing policy is independent of ID tokens, UserInfo, JAR and client
authentication. jwt uses query delivery for the supported code response.
Web Message clients MUST validate the provider origin, exact popup/frame window, message issuer and state, and accept only one result. Explicit modes use only the named opener or parent. Generic mode prefers the opener, then uses the parent only when an opener is absent. Invalid or closed receivers MUST NOT trigger a fallback transport.
Iframe use additionally requires an explicit provider framing allowance for the embedding origin and compatible client CSP/browser policies. Client registration alone does not authorize framing. Current live acceptance covers fresh password sign-in and cancellation from approved iframe origins; it does not establish remembered-session reuse or iframe MFA, email, federation or consent-denial coverage. See response modes for the complete delivery table, registration, SDK and browser requirements.
Consumer email sign-in
M7 supports a magic link and a one-time code in one email for an existing consumer account with a unique active verified address. Both share one-use proof and require the browser that requested the email. Link landing displays the requested address and requires explicit confirmation. Applications MUST use the normal hosted authorization-code flow and callback contract. The account's independent Email sign-in two-factor setting applies to both methods. See email sign-in.
Consumer two-factor authentication
Consumer accounts MAY enable independent TOTP checks for regular local password login, email sign-in, local-password Device Code approval, and remembered-account or existing-session authorization. Account/session intervals are Every time, 15 minutes, one hour, or eight hours. A completed proof is reusable only within the appropriate account, browser, authenticator, and authorization context.
Fresh federated authentication follows the provider's policy; later reuse of
the remembered M7 account follows the account/session setting. Refresh-token
requests and machine credentials do not prompt for these codes. Applications
MUST continue using M7's hosted authorization pages, preserve the normal OAuth
transaction, and handle a due prompt=none check as login_required with
error_reason=account_two_factor_required.
Recovery codes are single-use. M7's hosted recovery option offers full
authenticator unlink by default and always unlinks on use of the final code.
The settings page also supports TOTP, recovery-code, and eligible linked-account
unlink. These account features do not add a discovery flag or a new amr/acr
assurance guarantee. See two-factor authentication and recovery.
Client authentication
Each client has one registered token-endpoint authentication method. The same method applies wherever that method is advertised for the invoked endpoint.
| Method | Token | PAR | Device authorization | Introspection | Revocation |
|---|---|---|---|---|---|
none |
Yes | Yes | Yes | No | Yes |
client_secret_basic |
Yes | Yes | Yes | Yes | Yes |
client_secret_post |
Yes | Yes | Yes | Yes | Yes |
client_secret_jwt |
Yes | Yes | Yes | Yes | Yes |
private_key_jwt |
Yes | Yes | Yes | Yes | Yes |
tls_client_auth |
Yes | Yes | Yes | Yes | Yes |
self_signed_tls_client_auth |
Yes | Yes | Yes | Yes | Yes |
none identifies a public client with its exact client_id; it is not
anonymous access. A public client cannot use client_credentials or
introspection.
For client_secret_basic, the client identifier and secret are
application/x-www-form-urlencoded before Basic construction, as required by
the OAuth client-password contract. Clients SHOULD use a standards-compliant
library rather than constructing the header ad hoc.
For client_secret_jwt and private_key_jwt:
issandsubMUST both equal the exactclient_id;audMUST contain either the canonical issuerhttps://sso.user.m7.orgor the exact invoked endpoint URL;iatand unexpiredexpMUST be current;jtiMUST be nonempty and unique; and- a replayed, stale, incorrectly signed, or otherwise invalid assertion is
rejected as
invalid_client.
| Assertion method | Algorithms |
|---|---|
client_secret_jwt |
HS256, HS384, HS512 |
private_key_jwt |
RS256, RS384, RS512, ES256 |
Mutual-TLS client authentication
M7 supports both RFC 8705 authentication methods. A client using
tls_client_auth presents a certificate that chains to an M7-trusted client
CA and matches exactly one registered subject-DN or SAN selector. A client
using self_signed_tls_client_auth presents the exact self-signed certificate
represented by one key in its registered inline jwks or HTTPS jwks_uri.
The canonical issuer remains https://sso.user.m7.org. Clients discover and
use the dedicated mtls_endpoint_aliases when presenting a client certificate:
| Operation | mTLS endpoint alias |
|---|---|
| Token | https://mtls-sso.user.m7.org/token |
| PAR | https://mtls-sso.user.m7.org/par |
| Device authorization | https://mtls-sso.user.m7.org/device_authorization |
| Introspection | https://mtls-sso.user.m7.org/introspect |
| Revocation | https://mtls-sso.user.m7.org/revoke |
| UserInfo | https://mtls-sso.user.m7.org/userinfo |
The ordinary authorization endpoint, discovery documents, registration endpoint, and provider JWKS remain on the canonical SSO origin.
For either mTLS authentication method, the registration value
tls_client_certificate_bound_access_tokens=true requires certificate-bound
access and refresh tokens. M7 records the presented leaf certificate's
SHA-256 thumbprint as cnf."x5t#S256". Token refresh MUST present the same
certificate, and a protected-resource request MUST present the exact bound
certificate over mutual TLS; the token cannot be downgraded to bearer use.
When a token carries both DPoP and certificate confirmation members, both
sender constraints apply.
Provider-signed responses
| Response | Formats and algorithms |
|---|---|
| ID token | Signed JWT using a configured asymmetric profile or, for confidential clients, HS256/384/512 with a recoverable client secret; registration default is RS256 |
| UserInfo | JSON by default, or signed JWT using registered RS256 or RS512 |
| Provider JWKS | RSA, EC, OKP, and AKP signing keys selected by exact kid, matching alg, and algorithm-appropriate key parameters |
For a signed UserInfo response, the client MUST validate the JWS, canonical
issuer, its own client_id as audience, time claims, and exact sub equality
with the already validated ID token.
Signing algorithm selection
| Family | ID-token signing algorithms | Public JWK type |
|---|---|---|
| RSA PKCS#1 v1.5 | RS256, RS384, RS512 |
RSA |
| RSA-PSS | PS256, PS384, PS512 |
RSA |
| ECDSA | ES256, ES384, ES512, ES256K |
EC |
| Edwards | Ed25519, Ed448 |
OKP |
| ML-DSA | ML-DSA-44, ML-DSA-65, ML-DSA-87 |
AKP |
| HMAC (confidential clients) | HS256, HS384, HS512 |
None: shared client secret, never published |
Clients select id_token_signed_response_alg during registration; omission
continues to default to RS256. The protected alg MUST match the configured
algorithm and the selected verification key. HMAC requires the original client
secret and authoritative issued-token/state checks for API credentials. There is no automatic downgrade or
fallback to a different signing profile. UserInfo, client-authentication
assertions, JAR and DPoP retain their separate algorithm lists.
A third-party OIDC/JOSE client MAY use a supported profile when its verifier
supports that exact algorithm and key type. The generic EdDSA name is not an
alias for M7's Ed25519 or Ed448 values. Support for those explicit names and
for AKP/ML-DSA must be checked in the consumer's library.
Current-source M7 Identity SDK asymmetric verification supports the 15 public-key profiles through its
existing PHP paths and optional m7crypto backend, with an explicit allowlist
and compatible public-key resolution. Missing native support MUST fail rather
than bypass signature verification. Published SDK ZIPs remain at their existing
release capabilities until a new artifact includes the change. Local HMAC
verification additionally uses explicit hmac_secret and m7crypto; the Web
SDK session path uses authenticated introspection.
ML-DSA works in the tested device/native paths, but the current Web SDK's full-token cookies cannot generally accommodate it. Clients using that browser session integration MUST select a compact supported profile until storage and transport are revised and tested. See post-quantum storage limits and signing profiles and key formats.
Authorization requests, PAR, and JAR
An authorization request MUST use an exact registered HTTPS redirect URI,
response_type=code, PKCE S256, and a nonempty allowed resource-audience
set. M7 performs exact redirect matching; it does not support wildcard redirect
URIs, HTTP loopback exceptions, or custom-scheme exceptions in the current
profile.
PAR uses POST with an application/x-www-form-urlencoded body and the
client's registered authentication method. Successful PAR returns exactly the
standard top-level values below with HTTP 201 Created:
{
"request_uri": "urn:ietf:params:oauth:request_uri:OPAQUE_VALUE",
"expires_in": 600
}
The browser request then carries the issued request_uri; it MUST NOT override
the stored authorization parameters.
Signed Request Objects (JAR)
A client with an enabled JAR Request Policy MAY send a signed Request Object to
/authorize, either by value in request or through an exactly registered
HTTPS request_uri. The outer request MUST include client_id and exactly
one delivery parameter. JAR uses a dedicated client key source: exactly one
inline public JWKS or HTTPS JWKS URI, with one selected signing algorithm from
RS256, RS384, RS512, and ES256. It does not change the client's
registered token-endpoint authentication method or require every authorization
to use JAR.
The signed object MUST contain matching iss and client_id, an aud naming
the canonical authorization server, an integer exp, a fresh nonempty jti,
and the authorization parameters required for code flow. The signed inner
parameters are authoritative; outer authorization fields cannot override them.
PKCE, exact redirect matching, scopes, consent, authentication freshness, and
sender-constraint policies continue to apply.
The JWT aud identifies M7 as the recipient of the Request Object. It MUST NOT
be used to select a resource audience. This JAR profile uses the client's
complete registered resource-audience set; a separately signed resource subset
is not supported.
A customer-hosted object is fetched only from its exact registered public HTTPS URI, without redirects. After verification, M7 preserves the accepted parameters through login and consent; later content changes cannot alter that transaction. Replay, invalid signatures, invalid claims, unregistered URIs, and failed retrieval are rejected.
Discovery describes these capabilities through request_parameter_supported,
request_uri_parameter_supported, request_object_signing_alg_values_supported,
and require_request_uri_registration. See the discovery metadata
contract for their values
and JAR integration
for the request and hosting rules. JAR at /par, JAR metadata through Dynamic
Registration and encrypted Request Objects remain outside this JAR profile.
Signed JARM is supported separately for authorization responses.
Resource audiences and scopes
An audience identifies an intended resource. It is not proof that a client owns a domain or resource. M7 issues only audiences on the client's current administrative allowlist, and each resource server MUST still require its own exact audience and scopes.
Audience identifiers are exact, case-sensitive strings. They may be URLs or opaque identifiers. A grant may request a nonempty subset of its configured audiences. Where omission is permitted, omission selects the client's complete configured set. Refresh cannot add or replace a lineage's audience set.
The standard SSO scope catalogue is:
| Scope | Meaning |
|---|---|
openid |
Enables OpenID Connect, ID-token issuance, and UserInfo sub; required for UserInfo |
profile |
Standard profile claims and the compatible m7 profile projection |
email |
Primary active email and verification state when available |
groups |
Tenant-member organization and group projection |
offline_access |
Requests durable offline use; does not add UserInfo claims by itself |
Applications MUST request only an allowed subset. Consent and provider policy may narrow the result. Application-specific resource scopes may exist beyond the SSO catalogue.
Token issuance and refresh
The token endpoint accepts only POST with an
application/x-www-form-urlencoded body. Successful token requests return HTTP
200 and application/json.
Authorization codes are opaque, confidential, and single use. Redemption MUST use the exact redirect URI and PKCE verifier bound to the authorization transaction. Device codes are also confidential and single use after approved pickup.
client_credentials represents the OAuth application itself: its sub and
client_id identify the application. It does not impersonate a user and does
not return a refresh token.
Refresh belongs to one authenticated client and one immutable resource-
audience lineage. The normal profile rotates the refresh package. A client MUST
persist the complete successful replacement before discarding its preceding
package. A revoked, expired, malformed, foreign, or otherwise invalid refresh
credential returns HTTP 400 with error=invalid_grant.
M7 refresh packages may contain binding_chain and binding_link. The default
advisory binding policy permits a standard refresh request to omit these M7
extensions. Clients using a binding-required profile MUST retain and return
both values; legacy personal-lineage signing also requires its binding package.
The optional M7 acknowledgement refresh mode and /token/ack are extensions to
the base profile; ordinary integrations SHOULD omit refresh_mode.
DPoP sender constraint
M7 advertises RFC 9449 DPoP with exactly ES256. Dynamic Registration's
standard dpop_bound_access_tokens=true selects required DPoP. Omission or
false leaves DPoP optional, allowing an otherwise eligible request to opt in
with a valid proof. Internal M7 root-session proofing is a separate mechanism
and is not altered by a customer's DPoP registration setting.
A DPoP proof MUST:
- be a signed
dpop+jwtusingES256and a public JWK; - bind the exact HTTP method and normalized target URI;
- contain a current
iatand a fresh, single-usejti; and - contain the exact access-token
athfor protected-resource requests.
Authorization-code binding may use dpop_jkt in the authorization request or
PAR. PAR also accepts a DPoP proof; when both are present, their key
thumbprints MUST match. The token request MUST use the same key when the code
is bound.
A bound token response uses token_type=DPoP and carries cnf.jkt in the
access and refresh tokens. A protected-resource request then uses
Authorization: DPoP ACCESS_TOKEN plus a distinct fresh DPoP proof. An
unbound token uses token_type=Bearer and MUST NOT be upgraded to the DPoP
authorization scheme.
At the token endpoint, a missing or invalid proof required by client or grant
policy returns HTTP 400 with error=invalid_dpop_proof before a code or
device credential is consumed. At a protected resource, a missing, malformed,
stale, replayed, wrong-method, wrong-URI, or wrong-ath proof is rejected with
HTTP 401, error=invalid_dpop_proof, and WWW-Authenticate: DPoP
advertising algs="ES256". Scheme or key-binding confusion is rejected as
invalid_token with the same DPoP challenge.
M7 does not currently issue DPoP-Nonce.
UserInfo and protected resources
UserInfo accepts GET or form-encoded POST. A standard request authenticates
only with the access token; M7 derives the owning client from the validated
token. An optional legacy client_id request value is accepted only as an
additional exact-match assertion and never overrides the token.
UserInfo requires an active access token with openid. It does not require a
dedicated UserInfo audience, but it rechecks that the token's full signed
audience and scope sets remain allowed by current client policy. A resource API
still MUST enforce its own exact audience, client, scope, principal, active
state, and sender constraint.
JSON UserInfo success uses HTTP 200 and application/json; registered signed
UserInfo uses HTTP 200 and application/jwt. Clients MUST compare UserInfo
sub exactly with the validated ID-token sub.
Introspection, revocation, and end session
Introspection is restricted to confidential clients. An authenticated client
may inspect only a token issued to that exact client_id. Success returns HTTP
200 with active and, only when active and authorized, the available token
metadata. Clients and resource servers MUST treat active=false as unusable.
Public and confidential clients may revoke their own credentials. A valid
revocation request returns HTTP 200, application/json, and exactly {}
whether the submitted token was active, malformed, expired, already revoked,
or owned by another client. This opaque response prevents token-existence and
ownership probing; a foreign token is not revoked.
The end-session endpoint accepts GET or POST. A validated
post_logout_redirect_uri must exactly match the client's registered list.
M7 returns to an approved URI with HTTP 303; otherwise it completes only the
generic M7 sign-out experience.
Dynamic Client Registration
Dynamic Client Registration uses authenticated POST /register with a JSON
object and returns HTTP 201 on success. Defaults are:
| Metadata | Default |
|---|---|
application_type |
web |
response_types |
["code"] |
grant_types |
["authorization_code"] |
token_endpoint_auth_method |
client_secret_basic |
id_token_signed_response_alg |
RS256 |
| UserInfo response | JSON |
dpop_bound_access_tokens |
false |
Public clients MUST explicitly request token_endpoint_auth_method=none.
Secret-based registration returns the plaintext secret once; clients MUST
store it securely because it is not later retrievable.
An mTLS registration selects either tls_client_auth or
self_signed_tls_client_auth. CA-issued authentication requires exactly one
of tls_client_auth_subject_dn, tls_client_auth_san_dns,
tls_client_auth_san_uri, tls_client_auth_san_ip, or
tls_client_auth_san_email. Self-signed authentication requires exactly one
of inline jwks or HTTPS jwks_uri, and the selected JWK must represent the
presented self-signed certificate. The optional
tls_client_certificate_bound_access_tokens boolean defaults to false and
is valid only with an mTLS authentication method.
Registration creates a protocol-valid client but deliberately does not grant a
resource audience. An administrator must configure at least one exact
allowed_audiences value before token issuance. M7 does not currently expose
public resource-authority packs or permit a client to grant itself an arbitrary
audience.
Error and rate-limit contract
Protocol errors use an OAuth JSON object with error and, where safe,
error_description. Clients MUST branch on the stable error value rather
than prose and MUST safely tolerate unknown error values. Browser
authorization errors return only to an already validated redirect URI and
preserve the transaction's exact state.
Rate-limited protocol requests return HTTP 429,
error=too_many_requests, and a Retry-After header describing the current
cooldown. A client MUST stop and wait; it MUST NOT rapidly retry. A request
during an active rolling penalty may restart one configured quiet period from
the latest attempt, but it does not add a second penalty duration to the
existing expiry. Defensive thresholds are intentionally not part of the
public profile.
Deliberately unsupported or pending features
| Feature | Status in this profile |
|---|---|
| OpenID certification | Not claimed; official conformance-suite execution remains pending |
JAR at /par, JAR Dynamic Registration metadata, and encrypted Request Objects |
Unsupported; signed JAR is enabled per client at /authorize |
| Encrypted JARM authorization responses | Deferred; the four signed JARM modes are supported |
| Signed resource-audience subsets in JAR | Deferred; JAR uses the complete registered resource set |
| JWE-encrypted ID tokens or UserInfo | Unsupported |
| OAuth Token Exchange | Unsupported; possible future profile |
| DPoP nonce | Not issued |
| Implicit or hybrid flow | Unsupported |
PKCE plain |
Unsupported |
| Public-client introspection | Unsupported |
| Automatic DCR audience or authority packs | Deferred; administrative audience assignment remains required |
Executable profile assertions
These stable assertion IDs let conformance tests and release evidence point to the public rule without exposing private fixtures or operations.
| Assertion | Required result |
|---|---|
M7P-DISC-001 |
Both discovery URLs return the canonical issuer and identical advertised capability sets |
M7P-AUTH-001 |
Authorization code with exact redirect, state, nonce, and PKCE S256 succeeds; wrong state, nonce, audience, or verifier fails closed |
M7P-RESP-001 |
All ten registered response modes deliver success and safe errors; omitted request mode selects query; unknown/disallowed modes fail without fallback; PAR/JAR retain the selected mode |
M7P-JARM-001 |
Four JARM modes carry one signed response with exact RS256/RS512 policy, issuer, client audience, expiry and state; tampered, unsigned, mixed or mismatched responses fail before code exchange |
M7P-WMSG-001 |
Explicit opener/parent and generic receiver selection enforce exact window, origin, issuer and state, one-use receipt, and receiver cleanup; missing/closed receivers fail without fallback |
M7P-PAR-001 |
Successful PAR returns HTTP 201 with top-level string request_uri and numeric expires_in |
M7P-JAR-001 |
An enabled client can complete signed direct and registered-URI authorization; signatures, client/issuer/audience/time binding, replay rejection, URI restrictions, immutable continuation, and ordinary authorization/PAR regressions enforce this profile |
M7P-CLIENT-001 |
Every advertised client-authentication method and algorithm reaches grant processing; invalid or replayed credentials return invalid_client |
M7P-TOKEN-001 |
Successful grants return the registered signing profile and correct principal, audience, scope, and client binding |
M7P-REFRESH-001 |
Valid refresh rotates successfully; revoked or invalid refresh returns HTTP 400 invalid_grant |
M7P-DPOP-001 |
Bound issuance, refresh, and resource use preserve one exact cnf.jkt; downgrade and proof negatives fail with the documented 401 challenge |
M7P-USERINFO-001 |
JSON and signed UserInfo validate and bind sub exactly without requiring a request client_id |
M7P-LIFE-001 |
Introspection, opaque revocation, post-revocation inactive state, and end-session redirect controls match this profile |
M7P-DCR-001 |
Registration defaults are authoritative, unsupported metadata fails without a client, and no resource audience is self-granted |
M7P-RATE-001 |
Limiting returns 429 plus accurate Retry-After; cooldown recovery requires no protocol-bound administrative token |
M7P-MTLS-001 |
Both advertised RFC 8705 authentication methods work through the discovered aliases; bound issuance and refresh preserve one exact cnf."x5t#S256"; UserInfo and resource use require that certificate; introspection and revocation accept the registered mTLS method; and missing, mismatched, untrusted, expired, or revoked certificates fail closed |