creativecrafts / laravel-sso
Multi-tenant SSO package for Laravel supporting OIDC and SAML 2.0 with provisioning, multiple guards, and optional Inertia admin UI.
Fund package maintenance!
Requires
- php: ^8.3
- ext-dom: *
- ext-libxml: *
- ext-openssl: *
- ext-zlib: *
- illuminate/contracts: ^12.0|^13.0
- illuminate/database: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- robrichards/xmlseclibs: ^3.1.4
- spatie/laravel-package-tools: ^1.93
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.27
- nunomaduro/collision: ^8.9
- orchestra/testbench: ^11.1.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- rector/rector: ^2.3
README
Generic OIDC and SAML 2.0 SSO for Laravel, with multi-tenant support, user provisioning, identity linking, redacted audit logging, replay prevention, and configurable throttling on public SSO endpoints.
Compatibility
This package supports the runtime constraints declared in composer.json:
- PHP
^8.3(8.3, 8.4, 8.5) - Laravel / Illuminate
^12.0|^13.0
CI validates PHP 8.3–8.5 across Laravel 12 and 13. See composer.json for authoritative constraints.
Documentation
| Guide | Description |
|---|---|
| Getting Started | Install → first OIDC login |
| Configuration Reference | All config keys, env vars, IdP JSON shapes |
| Integration Guide | Policies, events, tenancy, guards, extension |
| Admin API | JSON admin API + UI scaffold |
| Operator Guide | Production operating model |
| Deployment Guide | Staging/production checklist |
| Security Guide | Hardening and operational security |
| Troubleshooting Guide | Common issues |
| Error Catalog | Exceptions and HTTP status mapping |
| Upgrade Guide | Migration and rollout notes |
| Auth Attempt Lifecycle | Callback state machine |
| Database Schema | Tables, columns, indexes, relationships |
| Architecture Audit | Design boundaries and limitations |
| Maintainer Release Checklist | Release gates |
| Contributor Matrix Testing | Local PHP/Laravel matrix |
Installation
composer require creativecrafts/laravel-sso php artisan sso:install --run-migrations
sso:install publishes config (sso-config), migrations (sso-migrations), and optional UI assets (sso-ui).
Manual publish:
php artisan vendor:publish --tag=sso-config php artisan vendor:publish --tag=sso-migrations php artisan migrate
Database foundation
Published migrations create:
- tenants
- identity providers
- connections
- auth attempts
- external identities
- audit logs
Do not treat the database layer as optional.
Quick start
php artisan sso:make-tenant "Acme Corp" php artisan sso:make-idp {tenant_ulid} "Acme OIDC" --protocol=oidc php artisan sso:make-connection {tenant_ulid} {idp_id} "Acme Connection" php artisan sso:doctor --strict
Configure IdP credentials (admin API or tinker), then add a login button using connection ULID:
<x-sso-button tenant="{{ $tenantUlid }}" connection="{{ $connectionUlid }}" />
Full walkthrough: Getting Started.
Public SSO routes
GET /sso/{tenant_ulid}/{connection_ulid}/redirect
GET /sso/{tenant_ulid}/{connection_ulid}/callback (OIDC)
POST /sso/{tenant_ulid}/{connection_ulid}/acs (SAML)
GET /sso/{tenant_ulid}/{connection_ulid}/metadata (SAML SP)
Optional: ?redirect_to=/dashboard on the redirect route (validated for safety).
Helper: sso_redirect_url($tenantUlid, $connectionUlid, $redirectTo = null).
Provisioning and identity linking
Provisioning and identity linking are deny-by-default. A successful callback creates or links a local user only when:
- the host binds custom
ProvisioningPolicy/IdentityLinkPolicyimplementations, or - package-wide defaults are enabled in
config/sso.php, or - the connection opts in via
sso_connections.settings
Connection settings override package defaults:
$connection->settings = [ 'allow_provisioning' => true, 'allow_identity_linking' => true, ];
Claim-aware example policies: GroupRequiredProvisioningPolicy, GroupRequiredIdentityLinkPolicy. See Integration Guide.
Admin API and UI scaffold
The JSON admin API manages tenants, identity providers, and connections. Enable with SSO_UI_ENABLED=true and register a manageSso gate.
An optional Inertia UI scaffold can be published (sso-ui tag); full CRUD screens are host-app responsibility.
Details: Admin API.
Security highlights
- IdP URL trust policy (HTTPS, no private hosts by default, DNS-checked outbound calls)
- OIDC: PKCE S256, nonce, RS256 JWKS validation, encrypted PKCE verifiers
- SAML: strict XML shapes, signature validation, optional AuthnRequest signing (fail-closed)
- Auth-attempt row-lock lifecycle with deferred consumption
- Redacted audit logging; encrypted IdP config and external identity claims by default
- Independent rate limiters:
sso.redirect,sso.callback,sso.acs,sso.metadata - Safe
redirect_tovalidation at storage and callback time
Full checklist: Security Guide.
Further reading:
- Threat Model — STRIDE analysis and integrator checklist
- Security Best Practices Report — remediation status and operational guidance
Claims persistence
External identities persist minimized canonical claims by default:
'claims' => [ 'persist_raw' => false, 'persist_groups' => true, 'max_group_items' => 100, 'encrypt_persisted' => true, ],
Auth attempt lifecycle
Callbacks use reserve → validate → consume (or retryable failure). See Auth Attempt Lifecycle.
Data retention
Schedule daily pruning:
Schedule::command('sso:prune --attempts-days=7 --audit-days=30')->daily();
Testing
composer test composer ci # full quality gate
Upgrade guidance
Review Upgrade Guide and CHANGELOG before upgrading.
Changelog
See CHANGELOG.
Contributing
See CONTRIBUTING.
Security Vulnerabilities
See SECURITY.md or the GitHub security policy.
Credits
License
MIT — see LICENSE.md.