Your own Identity & Authorization control plane — and a web console to run it — deployable in minutes.
One Laravel 13 app that installs the entire Laravel IAM ecosystem and ships a React admin console to
manage users, roles & grants, sessions, audit, access reviews, AI anomaly recommendations and apps.
📚 Full ecosystem docs · 🚀 Zero-to-working tutorial · ☁️ Deploy on Laravel Cloud
- What this is
- What it's for
- What's inside
- Requirements
- Set it up locally (step by step)
- First steps after login
- Deploy on Laravel Cloud (step by step)
- Connect your apps
- How it works (architecture)
- Configuration reference
- The ecosystem
- License
laravel-iam-console is the deployable host application for Laravel IAM —
an open-source, self-hosted Identity & Authorization control plane for Laravel.
laravel-iam-server is a package, not an app: you can't deploy it directly. This repo is the app that
installs it — pre-wired with every IAM package, a login backend, a super-admin seeder, and a web admin
console on top. Clone it, point it at a database, deploy it, seed a super-admin, and you have a running IAM
server with a UI. Your other applications then install
padosoft/laravel-iam-client and ask this server for
authorization decisions.
- Run your own IAM/IdP instead of a SaaS: identity, RBAC + ABAC + ReBAC authorization, OAuth2/OIDC, tamper-evident audit, and governance — hosted by you, owned by you.
- Manage it from a browser: create users, assign roles & permissions, review sessions, read the audit trail, run access-review campaigns, and see AI least-privilege/anomaly recommendations — no CLI required.
- Authorize every app you own against one control plane: PHP apps via
laravel-iam-client, and Node / React Native / Rust apps via the official SDKs.
A React 19 + Vite 8 + Tailwind 4 single-page app (resources/console), served by the app behind login. Every
screen talks only to the server's real Admin API (/api/iam/v1) — nothing is faked.
| Screen | What you do there |
|---|---|
| Dashboard | At-a-glance metrics (decisions, grants) and recent activity. |
| Users | List & search users, open a user to see effective permissions, create a user, suspend / reactivate, and revoke all their sessions. |
| Roles & Grants | Assign a permission or role to a user with the policy wizard — preview the impact (who's affected, conflicts) then commit a permit / deny grant. |
| Sessions | List active sessions and revoke them individually. |
| Audit log | Browse audit events and verify the tamper-evident hash-chain on demand. |
| Access reviews | Create certification campaigns, open/close them, and certify or revoke each access item. |
| Recommendations | AI & least-privilege findings — unused grants, over-privileged subjects (advisory, draft-only). |
| Applications | The registered applications and their manifests. |
| Decision playground | Ask the PDP a check / explain and see the real ALLOW/DENY + the reasoning. |
Note on user creation. The IAM Admin API intentionally does not create users (identities come from your app's auth / OIDC / directory). The console owns user creation via a small app endpoint (
POST /api/console/users), gated by theiam:users.managepermission; everything else is the real Admin API.
Installed and wired for you in one Laravel 13 app:
- laravel-iam-server — identity, PDP (RBAC + ABAC + ReBAC), Application Registry + manifests, OAuth2/OIDC, tamper-evident audit, governance/IGA, and the Admin API.
- laravel-iam-client —
iam.auth/iam.canmiddleware + Gate adapter (for in-app authorization). - laravel-iam-ai — advisory-only AI governance (redaction + hallucination-guard + audit), disabled by default.
- laravel-iam-directory — optional LDAP/AD login + JIT provisioning.
- laravel-iam-bridge-spatie-permission — migration bridge from spatie/laravel-permission.
- laravel-iam-contracts — shared interfaces & DTOs (transitive).
- Laravel Fortify — the web login backend for the IdP.
SuperAdminSeeder— bootstraps the first super-admin (granted everyiam:*permission).
- PHP 8.4+ (Laravel 13 requires Symfony 8 → PHP 8.4). The IAM packages themselves are 8.3+.
- Composer 2.
- Node 20+ and npm (to build the console UI).
- A database — SQLite works out of the box for local; Postgres or MySQL for a real deployment.
- No Redis, no S3 required (see How it works).
# 1. Clone
git clone https://github.com/padosoft/laravel-iam-console
cd laravel-iam-console
# 2. Environment + app key
cp .env.example .env
composer install
php artisan key:generate# 3. Create the schema (all iam_* tables) on SQLite by default
php artisan migrate✅ You should see ~20 migrations run (
iam_core_tables,iam_signing_keys,iam_sessions,iam_audit_tables,iam_applications_and_manifests, …).
# 4. Seed the first super-admin (reads IAM_SUPERADMIN_* from .env)
php artisan db:seed✅ Output:
Super-admin ready: admin@example.com (… iam:* permissions granted).The dev default isadmin@example.com/password— changeIAM_SUPERADMIN_PASSWORDin.envfirst for anything non-local.
# 5. Build the console UI (or `npm --prefix resources/console run dev` for hot reload)
npm --prefix resources/console install
npm --prefix resources/console run build✅ Emits
public/console/(the built SPA). Without this,/consolereturns a "UI not built" hint.
# 6. Serve
php artisan serveOpen http://localhost:8000 → you're redirected to the login → sign in as the super-admin → the console opens. That's it.
Do these once to see the whole thing working (this is exactly what the automated E2E test does):
- Register an application. Go to Applications (or apply a manifest via
php artisan iam:manifest:apply <file> --approve) to create an app + its permissions/roles catalog. - Create a user. Users → Create user (name, email, password).
- Assign access. Roles & Grants → pick the user, choose a permission or role (e.g.
warehouse:stock.adjust), Preview impact, then Commit grant. - Prove it. Decision playground →
checkthat user against the permission → ALLOW. Check a permission they don't hold → fail-closed DENY. - Watch the trail. Audit log → your changes are there; Verify chain confirms the hash-chain is intact.
You need only an app + a database. No Redis, no object storage.
- Push this repo to GitHub (your fork/copy).
- Create a Laravel Cloud project and connect the repository.
- Add a database (Postgres or MySQL) in the project — Laravel Cloud injects the
DB_*env. - Set environment variables (Project → Environment):
APP_URL=https://your-iam.example.com IAM_ISSUER=https://your-iam.example.com IAM_KMS_DRIVER=local SESSION_DRIVER=database CACHE_STORE=database QUEUE_CONNECTION=database IAM_SUPERADMIN_EMAIL=you@example.com IAM_SUPERADMIN_PASSWORD=a-strong-password
- Set the deploy/build command — build the console UI, migrate, and seed the super-admin:
composer install --no-dev --optimize-autoloader npm --prefix resources/console install --no-audit --no-fund && npm --prefix resources/console run build php artisan migrate --force php artisan db:seed --class=SuperAdminSeeder --force - Enable the scheduler (a Laravel Cloud toggle) — it drives the only async work (audit checkpoints, webhook delivery, access-review reminders) and needs no Redis.
- Deploy, then sign in at your URL as the super-admin. You now run IAM as a service, with a console.
Each consuming app installs the client and points at your server:
composer require padosoft/laravel-iam-clientIAM_CLIENT_MODE=http
IAM_CLIENT_BASE_URL=https://your-iam.example.com/api/iam/v1
IAM_CLIENT_APP=your-app-keyRoute::middleware(['iam.auth', 'iam.can:invoices.view'])->group(function () {
Route::get('/invoices', InvoicesController::class);
});Non-PHP apps use the Node, React Native or Rust SDK against the same server.
- Session-authenticated Admin API. The server can auto-register the Admin API under
/api/iam/v1with Bearer auth; this app disables that (config/iam.php→iam.admin.register_routes = false) and re-serves the same routes under thewebgroup.App\Iam\SessionAdminActorResolverresolves the Admin API actor from the operator's Fortify session, so the console calls the API same-origin with the session cookie — no browser tokens. Authorization is unchanged: every route still asks the PDP viaiam.can, fail-closed. - Super-admin = all
iam:*grants. There is no wildcard in the PDP, soSuperAdminSeedergrants the first user everyiam:*permission the Admin API declares. Manage further users/roles from the console. - Database-only infrastructure.
SESSION/CACHE/QUEUE=database; ES256 signing keys are generated and stored iniam_signing_keys(IAM_KMS_DRIVER=local, KEK derived fromAPP_KEY). Add Redis/KMS only at scale. - Passkeys are deferred.
laravel/passkeysisn't installable on Laravel 13 yet (itsweb-auth/webauthn-libpinssymfony/clock ^6|^7while Laravel 13 ships Symfony 8). Fortify (username/password) is the login backend until upstream supports Symfony 8.
See CLAUDE.md and .claude/skills/iam-console-dev for
the developer-facing details, and .claude/rules/rule-ship-workflow.md
for the CI/ship workflow (local-green → PR → Copilot → testE2E label → E2E CI).
| Variable | Default | Purpose |
|---|---|---|
IAM_ISSUER |
APP_URL |
OAuth/OIDC token issuer — set to your public URL in production. |
IAM_KMS_DRIVER |
local |
Signing/envelope key storage. local keeps keys in the DB (no external service). |
IAM_ADMIN_AUDIENCE |
(empty) | Only needed if you also expose the Admin API to Bearer-token clients. |
IAM_SUPERADMIN_NAME / _EMAIL / _PASSWORD |
Super Admin / admin@example.com / password |
The first super-admin created by the seeder. Change before deploying. |
SESSION_DRIVER / CACHE_STORE / QUEUE_CONNECTION |
database |
No Redis required. |
IAM_AI_ENABLED / IAM_AI_PROVIDER |
false / disabled |
Advisory-only AI. Real sovereign transports regolo (EU) and ollama (on-prem) ship in laravel-iam-ai; set IAM_AI_BASE_URL (+ IAM_AI_API_KEY for Regolo) to enable. Fail-safe otherwise. |
IAM_TRACER |
null |
Observability: null | log | otlp (native OpenTelemetry push to IAM_OTEL_ENDPOINT) | stack (both). |
This app is the host; the rest of Laravel IAM plugs into or consumes it. Every package has its own docs site:
- Server & modules (Packagist): server · client · ai · directory · bridge-spatie-permission · contracts
- Client SDKs: node · react-native · rust
MIT © Padosoft. Part of the Laravel IAM ecosystem.







