Deployment
The server is a normal Laravel package, so it deploys like any Laravel app — but it’s an IAM control plane,
so a few things deserve extra care.
Database
Use MySQL or PostgreSQL in production (SQLite is fine for dev/CI). The IAM tables carry your identity
and audit data — back them up, and treat the audit tables as append-only (never edit rows; it breaks the
hash-chain).
Key material
- OAuth encryption key — set
IAM_OAUTH_ENCRYPTION_KEY(base64, 32 bytes). Don’t rely on the
APP_KEY-derived dev default. - Signing keys — ES256 keys in
iam_signing_keyssign tokens; rotate them periodically (new public key
is published in JWKS before signing with it, so in-flight tokens keep verifying). - Crypto backend — back
LocalKeyProviderwith a real KMS in production (AWS KMS / Secrets Manager via
theaws/aws-sdk-phpsuggest dependency). - Admin audience — set
IAM_ADMIN_AUDIENCEso admin tokens are audience-pinned (fail-closed).
Queues for the outbox
Webhook/event delivery uses a transactional outbox dispatched
asynchronously — run a queue worker (and Horizon if you use it) so deliveries flow:
php artisan queue:work --queue=default
Schedule the maintenance commands
// app/Console/Kernel.php
$schedule->command('iam:audit:verify')->hourly(); // tamper-evidence stays green
$schedule->command('iam:audit:checkpoint')->daily(); // cheaper future verification
$schedule->command('iam:least-privilege:scan')->daily(); // fresh recommendations
$schedule->command('iam:reviews:remind')->dailyAt('09:00');// nudge reviewers
Health checks
Wire your orchestrator’s probes to the unauthenticated endpoints (same prefix as the Admin API):
GET /api/iam/v1/health # liveness
GET /api/iam/v1/ready # readiness (dependencies reachable)
See Observability.
Hardening checklist
| Item | Action |
|---|---|
| Token transport | bearer header only; TLS everywhere |
| Audience pinning | IAM_ADMIN_AUDIENCE set |
| Rate limits | tune iam.admin.rate_limit / iam.oauth.rate_limit, keep a ceiling |
| Secrets | write-only across the API; rotate, never read back |
| Tenant scope | preserved in any custom code (404, not 403) |
| Audit verification | scheduled + alerted on break |
| Backups | DB backups + SIEM export for retention |
The admin panel
The React panel is a separate static app that talks only to this API. Deploy it behind the same TLS and
auth boundary; it gets no special database access. See Admin panel.
When upgrading, run migrations in a maintenance window and verify the audit chain before and after. Never
hand-edit IAM tables to “fix” data — go through the Admin API so validation, idempotency and audit apply.
Next
- Configuration — every key you’ll set here.
- Observability — health, readiness, tracing.
- Securing the Admin API — the hardening detail.