CrossDomainSsoUser
This plugin provides end-user, cross-domain SSO through a broker/client architecture with a strict subject contract, explicit pre-linking, and fail-closed readiness gates.
Statusβ
| Key | Value |
|---|---|
| Layer | core |
| Tier | L1 |
| Status | wip |
| Version | 0.4.0 |
| Price | Free |
| Category | Security & Auth |
The P0 producer hardening is complete. Consumer wiring, targeted migrations, secret placement, identity pre-links, runtime activation, and production smoke tests have not been performed and require a separate Gate C approval. The default remains OFF.
Scopeβ
CrossDomainSsoUser connects end-user sessions across MSK services.
ExternalSsoModule: outbound SSO adapters from MSK to external OSS applications- ADR-040 Cross-Domain SSO: Platform Admin navigation between administration domains
CrossDomainSsoUser: an end-user flow where a broker proves an external subject and each client resolves its own local account
The broker stores SSO operational data only. Each client SaaS remains the source of truth for users and authorization, and it never trusts a broker database user ID or broker-side permissions as a local account.
P0 wire contractβ
The broker token response allows exactly the following five fields. Missing and additional fields are both rejected.
{
"contract_version": 1,
"provider_key": "opaque-provider-key",
"subject": "opaque-provider-subject",
"client_id": 42,
"issued_at": 1700000000
}
provider_keyis an immutable stable key assigned when the provider is created.subjectis an opaque provider identifier; its raw value is excluded from logs and diagnostics.- Broker user IDs, email, name, role, level, and permission data never cross the wire.
- A client accepts exactly one active, explicitly pre-linked
(provider_key, subject)mapping. - Email matching, prompt linking, JIT provisioning, and numeric-provider fallback are dormant in the P0 callback path.
Authentication flowβ
- Client
/sso/startcreates a 256-bit client state. - Broker
/sso/authorizeverifies an exact registered callback and creates a separate upstream state. - The provider callback consumes the upstream state once and issues a one-time authorization code containing a v1 assertion.
- The client callback consumes its client state once.
- Server-to-server token exchange validates a mandatory 32-byte-or-longer client secret before consuming the code.
- The client validates the stable pre-link, local user status, and Tenant/SaaS boundary before regenerating the session.
Client state and broker upstream state are not interchangeable. Each state/code uses a consumed marker so that only one request can win without assuming that payload deletion itself is atomic.
Secure defaultsβ
| Area | Policy |
|---|---|
| Callback | Exact registered HTTPS absolute URL; prefixes, wildcards, userinfo, and fragments are rejected |
| Client secret | At least 32 bytes on broker and client; empty or short values fail closed |
| Account link | Operator reviews a dry run before explicitly creating a pre-link |
| Readiness | sso:doctor and HTTP runtime use the same read-only policy |
| Remote probe | OFF by default; HMAC probe only when separately enabled on both sides |
| Data minimization | No PII, local user ID, authorization claim, or secret in assertions, diagnostics, or logs |
If any prerequisite fails, the doctor fails and SSO HTTP endpoints return 503. Saving an enabled value in Settings is not sufficient to activate the runtime.
Activation overviewβ
After a separate Gate C approval, activation must still be staged:
- Recheck broker/client wiring and the exact pending migration scope.
- Review and apply only the targeted additive migration.
- Place the same 32-byte-or-longer secret in both secret stores.
- Review an
sso:identity:linkdry run, then confirm only the approved account. - Pass
php artisan sso:doctoron broker and client. - Enable the broker first and, if separately opted in, verify the HMAC probe.
- Enable the client, then test positive, negative, replay, and existing password-login paths.
Rollback disables the client and broker again. The additive schema and pre-link row can remain for analysis and later reactivation; existing password login remains available.
Optional provider adaptersβ
The internal provider supplies the base contract. SAML, OIDC, and Social OAuth adapters are optional, and their packages are not part of the default distribution. Any installation requires source, transitive dependency, security, and license review followed by operator approval. No external package was installed for the P0 hardening.
Licenseβ
MIT
π View on Plugin Store: store.codebase.how/plugins/cross-domain-sso-user