theupriser/authkit (1.0.0)
Installation
{
"repositories": [{
"type": "composer",
"url": "https://git.upriser.nl/api/packages/theupriser/composer"
}
]
}composer require theupriser/authkit:1.0.0About this package
theupriser/authkit
A Laravel 13 package that provides a central authentication and identity provider (IdP). It can run embedded inside a mono-app or as a standalone microservice.
Features
- Password + TOTP MFA via Laravel Fortify and
pragmarx/google2fa - Passkeys / WebAuthn (FIDO2) via
laravel/passkeys - OAuth 2.0 + OIDC via Laravel Passport — Authorization Code + PKCE, Client Credentials, Personal Access Tokens
- JWT claims —
sub,email,name,avatar,roles,permissions,groups - Roles & permissions via
spatie/laravel-permission - OIDC discovery — JWKS endpoint, OpenID configuration
- Admin HTTP API — user management, roles, groups, passkeys, sessions, OAuth clients, scopes, audit log
- Redis event bus — bidirectional pub/sub for microservice integration
- Audit logging — all auth events written to
auth_audit_logs - Rate limiting & account lockout — configurable thresholds
- OpenAPI / Swagger UI — served at
/{prefix}/docs - Configurable — DB connection, table prefix, route prefix, event driver
Requirements
- PHP 8.3+
- Laravel 13
Installation
composer require theupriser/authkit
Publish the config:
php artisan vendor:publish --tag=authkit-config
Run the migrations:
php artisan migrate
Generate Passport keys:
php artisan passport:keys
php artisan passport:client --personal --name="AuthKit Personal Access Client" --provider=users
Configuration
# .env
AUTHKIT_PREFIX=auth # Route + table prefix
AUTHKIT_DB_CONNECTION=authkit # Database connection to use
AUTHKIT_LOCKOUT_ATTEMPTS=5
AUTHKIT_LOCKOUT_MINUTES=15
AUTHKIT_TOKEN_TTL=15 # Access token lifetime (minutes)
AUTHKIT_REFRESH_TTL=43200 # Refresh token lifetime (minutes, default 30 days)
AUTHKIT_EVENTS_DRIVER=null # null | redis
AUTHKIT_EVENTS_PREFIX=authkit # Redis channel prefix
AUTHKIT_REDIS_CONNECTION=default
AUTHKIT_DOCS_ENABLED=true
AUTHKIT_INVITATION_URL=/auth/invitation
AUTHKIT_RESET_URL=/auth/reset-password
Shared database
If AuthKit shares a database with the host app, set AUTHKIT_DB_CONNECTION to the same connection and all AuthKit tables will be prefixed (e.g. auth_users, auth_passkeys).
Own database
Add a dedicated connection in config/database.php:
'authkit' => [
'driver' => 'mysql',
'host' => env('AUTHKIT_DB_HOST', '127.0.0.1'),
'database' => env('AUTHKIT_DB_DATABASE', 'authkit'),
'username' => env('AUTHKIT_DB_USERNAME', 'root'),
'password' => env('AUTHKIT_DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation'=> 'utf8mb4_unicode_ci',
],
Routes
All routes are prefixed by AUTHKIT_PREFIX (default: auth).
Authentication
| Method | Path | Description |
|---|---|---|
POST |
/auth/login |
Password login, returns access + refresh token |
POST |
/auth/logout |
Revoke current token |
POST |
/auth/forgot-password |
Send password reset link |
POST |
/auth/reset-password |
Reset password via token |
POST |
/auth/mfa/enable |
Enable TOTP MFA |
POST |
/auth/mfa/verify |
Verify TOTP code |
Passkeys
| Method | Path | Description |
|---|---|---|
POST |
/auth/passkeys/login/options |
WebAuthn login challenge |
POST |
/auth/passkeys/login |
Authenticate with passkey |
GET |
/auth/passkeys |
List registered passkeys |
POST |
/auth/passkeys/register/options |
WebAuthn registration challenge |
POST |
/auth/passkeys/register |
Register a new passkey |
DELETE |
/auth/passkeys/{id} |
Remove a passkey |
OAuth 2.0 / OIDC
| Method | Path | Description |
|---|---|---|
POST |
/auth/oauth/token |
Issue access token |
POST |
/auth/oauth/token/revoke |
Revoke token |
POST |
/auth/oauth/token/introspect |
Introspect token |
GET |
/auth/userinfo |
OIDC userinfo endpoint |
GET |
/auth/.well-known/jwks.json |
Public keys (JWKS) |
GET |
/auth/.well-known/openid-configuration |
OIDC discovery document |
Admin API
All admin routes are protected by auth:api.
| Method | Path | Description |
|---|---|---|
GET/POST |
/auth/admin/users |
List / create users |
GET/PUT/DELETE |
/auth/admin/users/{id} |
Show / update / delete user |
GET |
/auth/admin/users/{id}/permissions |
Roles, permissions, groups |
POST |
/auth/admin/users/{id}/roles |
Assign role |
DELETE |
/auth/admin/users/{id}/roles/{role} |
Revoke role |
POST |
/auth/admin/users/{id}/groups |
Assign group |
DELETE |
/auth/admin/users/{id}/groups/{group} |
Remove from group |
GET/DELETE |
/auth/admin/users/{id}/sessions |
List / revoke sessions |
GET/DELETE |
/auth/admin/users/{id}/passkeys |
List / revoke passkeys |
GET/POST/DELETE |
/auth/admin/clients |
OAuth clients |
GET/POST/DELETE |
/auth/admin/scopes |
OAuth scopes |
GET |
/auth/admin/audit |
Audit log |
GET |
/auth/admin/audit/{user} |
Audit log for user |
API Docs
Swagger UI is available at /auth/docs (disable with AUTHKIT_DOCS_ENABLED=false).
Redis Event Bus
Enable Redis events by setting AUTHKIT_EVENTS_DRIVER=redis. AuthKit publishes to Redis channels when auth state changes, and can consume inbound commands from an admin app.
Published events (IdP → consumers)
| Channel | Trigger |
|---|---|
authkit.user.created |
User created via admin API |
authkit.user.updated |
User profile updated |
authkit.user.deleted |
User soft-deleted |
authkit.roles.changed |
Role assigned or revoked |
authkit.groups.changed |
Group membership changed |
authkit.token.revoked |
Token revoked |
authkit.passkey.registered |
Passkey added |
authkit.passkey.revoked |
Passkey removed |
authkit.mfa.enabled |
MFA activated |
authkit.password.reset |
Password was reset |
Consumed commands (admin app → IdP)
Start the consumer with:
php artisan authkit:consume-events
| Command | Action |
|---|---|
user.create |
Create a user |
user.update |
Update a user |
roles.assign |
Assign a role |
roles.revoke |
Revoke a role |
groups.assign |
Add to group |
groups.revoke |
Remove from group |
JWT Claims
Access tokens include the following custom claims in addition to standard OAuth claims:
{
"sub": "uuid",
"email": "user@example.com",
"name": "Rick Peters",
"avatar": "https://cdn.example.com/avatar.jpg",
"roles": ["admin", "editor"],
"permissions": ["users:read", "users:write"],
"groups": ["team-a"]
}
Running as a Microservice
AuthKit works as a standalone Laravel application. Point multiple apps at it as their OAuth 2.0 / OIDC provider using the Authorization Code + PKCE flow or Client Credentials for machine-to-machine auth.
Use the Redis event bus for decoupled communication between AuthKit and your admin application.
Testing
composer test
Tests use an in-memory SQLite database and run against the full package stack via orchestra/testbench.
Dependencies
Dependencies
| ID | Version |
|---|---|
| laravel/fortify | ^1.37 |
| laravel/framework | ^13.0 |
| laravel/horizon | ^5.0 |
| laravel/passkeys | ^0.1 |
| laravel/passport | ^13.7 |
| php | ^8.3 |
| pragmarx/google2fa | ^9.0 |
| spatie/laravel-permission | ^6.0 |
Development Dependencies
| ID | Version |
|---|---|
| orchestra/testbench | ^11.0 |
| phpunit/phpunit | ^11.0 |