Optional application logout hooks
The live Web/PHP 0.1.6 release exposes two optional mount points for applications that want local enforcement of provider logout notifications. Applications may leave them unconfigured and rely on their existing authority introspection/refresh-family revocation behaviour. There is no SQL requirement or SDK-provided store, queue or scheduler.
Configure application code
Set M7_LOGOUT_HOOKS_FILE to an absolute readable PHP file outside the public
document root and the installed SDK package. It returns an array of callables:
<?php
require '/etc/my-app/bootstrap.php';
return [
'ingest' => fn(array $event): bool => appLogout()->acceptVerifiedLogout($event),
'is_revoked' => function (array $context): bool {
if ($context['token_response'] && $context['id_token'] !== null) {
appSessions()->associateTokenResponse($context);
}
return appLogout()->isSessionRevoked($context);
},
];
The example services belong to your application and must be implemented.
Callbacks must return without printing, setting response headers or terminating
the request. Never log credential context.
Either callback can be omitted. An empty/unset setting disables both; a
configured invalid file or callback fails with HTTP 503
logout_hooks_unavailable when reached. Configuration loads once per request.
Ingest verified notifications
ingest receives the trusted configured issuer and client_id, verified
iat, exp, jti, and the verified sid and/or sub when present. It
receives no raw logout JWT or browser credentials. The existing signature,
issuer/audience, time, event, nonce and encryption checks run first.
Return exactly true after durable invalidation or durable queue acceptance,
including an already-applied duplicate. Only then does the receiver send
HTTP 200 ok. A throw, false or another return type gives HTTP 503
logout_ingestion_failed with retryable=true. Provider retry policy is
separate. Application exception details are excluded from SDK logs/responses.
Without ingest, the receiver still acknowledges validated receipt only.
Durable queue acceptance can leave an asynchronous enforcement delay unless
your checker also sees queued invalidations immediately.
Check session revocation
is_revoked receives these fields:
| Field | Meaning |
|---|---|
issuer, client_id |
Trusted deployment scope. |
stage |
Operation, such as session_use, refresh, ack, or token_response. |
access_token, refresh_token |
Selected credential inputs, strings or null. |
id_token, id_token_nonce |
Token-response ID token and expected login nonce, strings or null. |
token_response |
Whether this context comes from a successful server-to-server token response. |
Return exactly false to allow normal processing or true to stop it with
HTTP 401 session_revoked. Current-cookie operations clear SDK active/pending
cookies; pending ACK clears pending cookies. A supplied/candidate credential
does not clear a different current browser package. Throws/non-boolean results
give HTTP 503 logout_check_failed, retaining cookies for retry.
The checker runs before cookie/supplied-token session resolution, refresh, pending-package use/installation, ACK, active-cookie installation and UserInfo. It rechecks session resolution and refresh/ACK/UserInfo results after outbound work. Checks may repeat within a request. The SDK does not recall already-sent responses or make application storage and SDK requests atomic.
Your application must establish the session association. Credential strings
can be unvalidated browser input; the SDK supplies no decoded identity claim
as a trusted lookup key. At token_response, validate ID-token issuer,
client audience, nonce and signing/encryption policy before mapping credential
digests to the root sid/subject. Preserve root identity across refresh and
associate pending successors before ACK. Decide how unknown/legacy credentials
are handled; a fresh sign-in may be required. The token_response marker does
not itself assert ID-token claim validation. Existing signing/encryption
policies are unchanged.
Independent protected endpoints
Host-owned pages/APIs and independent application sessions need their own
integration. After loading the SDK shared.php, an endpoint can call:
m7_logout_require_session('my_api', ['access_token' => $accessToken]);
// Continue normal signature, proof, expiry and permission checks.
The helper returns when disabled or allowed, otherwise throws
M7LogoutHookException. If your framework owns exception handling, catch it
and deny access using httpStatus()/response(). Its optional third argument
all or pending clears SDK cookies on revocation; the default none suits
independent API credentials. This does not destroy a host PHP session or
replace endpoint authorization. Pure signature/expiry validation without a
revocation integration retains an access-token window until expiry.
Application storage duties
Scope writes/lookups by issuer and client; match sid/sub consistently.
Handle duplicates idempotently and delayed/out-of-order events without
revoking unrelated/new roots. Define the subject-only policy explicitly.
Make accepted writes visible to every worker/node. Checking must not consume
an invalidation needed by later requests. Keep records through the affected
credential, pending-package and application-session lifetimes; the logout
JWT's short expiry is not sufficient retention. Cleanup is application-owned.
The SDK's front-channel receiver retains its existing browser-cookie cleanup;
these hooks do not add verified front-channel ingestion or stored sid
matching. Register and test receivers using the
provider logout contract.