admin9 / laravel-oidc-server
OpenID Connect Server for Laravel Passport — adds OIDC Discovery, JWKS, UserInfo, Token Introspection, Token Revocation, and RP-Initiated Logout.
Requires
- php: ^8.2
- defuse/php-encryption: ^2.4
- laravel/passport: ^12.0|^13.0
- lcobucci/jwt: ^5.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- phpunit/phpunit: ^11.0|^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
OpenID Connect Server for Laravel Passport — adds OIDC Discovery, JWKS, UserInfo, Token Introspection, Token Revocation, and RP-Initiated Logout to any Laravel + Passport application.
Version 2.0 implements the authentication contract: real auth_time, max_age, and transaction-bound reauthentication. Host integration is required; see the 2.0 upgrade guide.
The 2.0 design defines the acceptance gates. Historical package delivery checks are recorded in implementation evidence; the stable release scope records subsequent acceptance and remaining limits.
Requirements
- PHP 8.2+
- Laravel 11, 12, or 13
- Laravel Passport 12 or 13
- Shared server-side sessions, session blocking, and shared Redis atomic state
Supported combinations: Laravel 11/12 with Passport 12/13 on PHP 8.2+, and Laravel 13 with Passport 13 on PHP 8.3+. Laravel 13 with Passport 12 is not compatible with upstream requirements. See the stable release scope and known limits.
Quick Start
Prerequisite: Laravel Passport must be installed and configured before using this package.
1. Install the package
composer require admin9/laravel-oidc-server
2. Implement the interface on your User model
use Admin9\OidcServer\Contracts\OidcUserInterface; use Admin9\OidcServer\Concerns\HasOidcClaims; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements OidcUserInterface { use HasOidcClaims { resolveOidcClaim as protected resolveDefaultOidcClaim; } // Optional: Override for custom claims protected function resolveOidcClaim(string $claim): mixed { return match ($claim) { 'nickname' => $this->display_name, 'picture' => $this->avatar_url, default => $this->resolveDefaultOidcClaim($claim), }; } }
The model override handles its named claims first. Other claims use the trait alias, which checks configured resolvers, sub, and the default claims map in that order. A null result is omitted.
3. Generate Passport keys
php artisan passport:keys
This creates the RSA key pair (storage/oauth-private.key and storage/oauth-public.key) needed for signing tokens.
4. Create an OAuth client
Create a client application that will use your OIDC server:
# For authorization code flow (recommended for web apps) php artisan passport:client # For client credentials grant (recommended for machine-to-machine, e.g., microservices) php artisan passport:client --client
You'll receive a Client ID and Client Secret — save these for configuring your client application.
Grant Type Guide:
- Authorization Code Flow: For web apps with user interaction, most secure
- Client Credentials Grant: For server-to-server API calls, no user involvement
- Password/device/custom user grants require a separate host OAuth entry; package endpoints reject them.
5. (Optional) Publish and customize the config
php artisan vendor:publish --tag=oidc-server-config
Edit config/oidc-server.php to customize scopes, claims, token TTLs, and more.
6. Connect host authentication
Implement AuthenticationRecorder calls after complete authentication and bind a ReauthenticationHandler, following the 2.0 integration guide. Configure shared sessions, locks and Redis before accepting authorizations.
Discovery is available at:
https://your-app.test/.well-known/openid-configuration
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/.well-known/openid-configuration |
GET | OIDC Discovery |
/.well-known/jwks.json |
GET | JSON Web Key Set |
/oauth/authorize |
GET | Authorization and authentication freshness |
/oauth/token |
POST | Protected code/refresh and client credentials |
/oauth/userinfo |
GET/POST | UserInfo |
/oauth/introspect |
POST | Token Introspection (RFC 7662) |
/oauth/revoke |
POST | Token Revocation (RFC 7009) |
/oauth/logout |
GET, POST | RP-Initiated Logout |
Configuration
After publishing the config file, you can customize various aspects in config/oidc-server.php:
User Model
By default, ID tokens use the provider model of the session guard selected by passport.guard. Override if needed:
'user_model' => \App\Models\User::class,
user_model does not select a login guard. Authorization and logout use passport.guard; the ID Token model and the Passport API provider for UserInfo must represent the same users. See alternate user models and guards for a complete Member configuration.
Passport Route Control
The package calls Passport::ignoreRoutes() by default to prevent route conflicts. Disable this if you need Passport's default routes alongside OIDC:
'ignore_passport_routes' => false,
Retained Passport authorization/token routes remain protected aliases of the package controllers. This does not restore password, device or custom user grants. A separate host OAuth entry requires its own controller, native server/response and distinct envelope key; see the independent host OAuth guide.
Default Claims Map
The HasOidcClaims trait resolves standard claims via a configurable map. Override to match your User model's schema:
'default_claims_map' => [ 'name' => 'name', // string = model attribute 'email' => 'email', 'email_verified' => [\Admin9\OidcServer\Services\DefaultClaims::class, 'emailVerified'], 'updated_at' => [\Admin9\OidcServer\Services\DefaultClaims::class, 'updatedAt'], ],
For custom claims (e.g., nickname, picture), use claims_resolver or override resolveOidcClaim() in your User model.
Use attribute strings or static callable arrays when caching configuration. Closures in configuration cannot be serialized by php artisan config:cache; update previously published closure mappings before caching.
Other Options
- Scopes & claims mapping —
scopes,claims_resolver - Token TTLs —
tokens.access_token_ttl,tokens.refresh_token_ttl - Reserved ID Token TTL —
tokens.id_token_ttlis not active; ID Token expiry follows the access token expiry - Route middleware —
routes.discovery_middleware,routes.token_middleware,routes.userinfo_middleware - Passport auto-configuration —
configure_passport(set tofalseto configure Passport yourself)
See the Configuration Reference for all available options.
Documentation
- Architecture
- Configuration Reference
- Endpoint Reference
- Claims Resolution
- Extension Points
- Troubleshooting
License
Security upgrade
Read the 2.0 upgrade guide for logout confirmation, exact callbacks, resource-server authorization and historical-grant handling.
See the published security advisory GHSA-7wgf-3xc4-jx69 for the original report, fixed versions and maintainer follow-up.