Sign in with M7 on a PHP site
The announcement said you can start. This is the first path: put Sign in with M7 on a PHP site using web-php 0.1.3.
The package is a same-origin backend-for-frontend. It owns OAuth state, PKCE, the code exchange, and HttpOnly session cookies. Your app owns pages, routing around /m7_sso_session, and when to ask for the current session. Do not rename the installed directory.
The full contract is the website installation guide. This post is the copyable spine.
1. Register the app
Create a development account, then register an OAuth application. The redirect URI for the default install is exact:
https://YOUR_APPLICATION_ORIGIN/m7_sso_session/callback
You will need the origin, client ID, token-endpoint authentication method, client secret if the client is confidential, authorization and token endpoints, acknowledgement endpoint, fingerprints, refresh mode, and a same-origin post-login URL. Issuer is https://sso.user.m7.org. PKCE is S256 only.
2. Verify the zip
m7-identity-web-php-0.1.3.zip
m7-identity-web-php-0.1.3.zip.sha256
m7-identity-web-php-0.1.3.zip.manifest.json
shasum -a 256 -c m7-identity-web-php-0.1.3.zip.sha256
unzip m7-identity-web-php-0.1.3.zip -d ./staging
Copy only m7_sso_session into the public document root. Keep the docs, manifest, and checksums out of the web root. Do not put a .env, client secret, or pending-envelope key inside that directory.
3. Configure the PHP worker
Set the registered M7_* values on the Apache / PHP-FPM process that serves the site. Fingerprints accept 64 hex or 43 unpadded base64url characters; the SDK still sends lowercase hex on the wire. Reload the worker after changes. The CLI environment is not the web worker.
4. Start login and read the session
window.location.assign("/m7_sso_session/");
const response = await fetch("/m7_sso_session/me", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: "{}",
});
const session = await response.json();
if (!response.ok || session.ok !== true) {
throw new Error(session.error?.message || "M7 session request failed");
}
Treat HTTP status and ok together. Keep any access token from /me in memory. /profile uses the HttpOnly cookie and does not return the token. Never call /callback-process yourself; the package callback page owns that hop.
A GET to /m7_sso_session/me should be 405. Direct PHP filenames in the package should be rejected.
5. Confirm the loop
On a non-production registration, run login, callback, acknowledgement, /me, /profile, refresh, and logout through the real HTTPS origin before you point a production client at it.
If the site already brokers GitHub or Discord itself, use the OIDC-Connect PHP pattern so M7 is one button beside the others. The website still owns local accounts and linking. Do not key accounts on email alone.
PHP 8.1+, OpenSSL, and cURL. License is MTL-10. Packagist is not available.
That is the install. Next is policy: people, machines, and tenants are not the same principal.