Skip to content
Talk to our solutions team

Operations

The database itself is the only external prerequisite — iam.svc never creates databases and never issues DDL at serve time.

Terminal window
iam.svc config generate bootstrap-dev > .iam.yaml
iam.svc data bootstrap -f .iam.yaml # tenant plane: schema + tables + ledger
iam.svc data bootstrap -f .iam.yaml --tenant superadmin # control plane: registry, operators, keyring
iam.svc seed -f .iam.yaml --email [email protected] --password '' \
--firstname Admin --lastname User
iam.svc -f .iam.yaml -l info # serve on 127.0.0.1:5030
  • data bootstrap creates the schema if missing and applies one diff-based plan, lock-less and idempotent — safe to re-run.
  • seed creates the control-plane superadmin and a tenant admin through the engine (hashing and access rules apply); idempotent. The HTTP alternative for the very first superadmin is POST /auth/bootstrap, gated by bootstrap.token and self-closing.
  • Reserved planes migrate like tenants: --tenant <c>:<p>:<e>:superadmin, or --scope shared.
  1. Add the tenant node to the tenant hive (dbpool with schema:, meta.url — see Configuration).
  2. Ensure the database exists (IaC — not iam’s job).
  3. Register + provision, either over HTTP (POST /superadmin/registry/tenants, then …/provision) or in one CLI step:
Terminal window
iam.svc tenant provision -f .iam.yaml --tenant acme:forge:prod:tenant-a \
--email [email protected] --password ''

Register → bootstrap → seed → activate, idempotent. There is no product allow-list to edit — a product registers itself on first request. 4. The tenant admin logs in with the tenant’s own CPET headers.

Steady-state changes are plan-based, risk-gated, and audited:

Terminal window
iam.svc data plan generate -f .iam.yaml --tenant <cpet> [--allow-drops]
iam.svc data plan show <plan-id>
iam.svc data plan apply <plan-id> --confirm-risk medium [--dry-run]
iam.svc data seed run|list
iam.svc data applied list --plan-id <id>

All commands take -f <config> --tenant <cpet> --datastore --output table|json and operate on one CPET at a time. Plan apply over HTTP requires a superadmin token (403 v2.requires_superadmin is working as intended).

  • Managed tenants: instant revoke (POST /internal/session/revoke), enumerate / log-out-everywhere (/list), fixation rotation (/rotate).
  • Stateless tenants: revocation only via refresh-family logout; access tokens live out their 15 minutes.
  • Concurrency is enforced atomically per (CPET, principal): on_limit: reject → 409-class error; evict_oldest revokes the oldest session with reason concurrent_evict.
  1. Grant the operator impersonate-readonly or impersonate (neither is implied by root) plus a grant row for the target tenant.
  2. The target user must have allow_impersonation: true (default false).
  3. POST /superadmin/impersonate with a mandatory reason.
  4. The session is force-managed — the user and tenant admin can see it and kill it.
  5. Break-glass without user opt-in is deliberately not an API — that path is direct DB access with your own change control.
  • Every auth flow emits before/after events on the auth event bus; wire an event logger to persist them (the default is a no-op). Script hooks (pointcuts) can react to auth events.
  • Rate limits on login/MFA/reset/magic/token-exchange/API-key issue; constant-cost hashing on the user-not-found path; PKCE + 10-minute OAuth state; single-use TOTP; refresh reuse detection.
  • No /health / /ready — probe TCP or an auth flow.
  • Metrics are defined but not yet recorded.
  • JWKS caps at 100 keys, WebAuthn credentials at 50, silently.
  • Generated-key rotation has no endpoint/schedule yet.
  • Refresh-token tombstones lack a retention sweep.
SymptomCause / action
500 issue_failed after an upgradeStale refresh-token schema — iam.svc data plan generate + apply
400 invalid tenantCPET headers match no configured tenant node
500 engine_unavailableCPET has no resolvable tenant config, or its database is down
401 on /rest with “no configured URL for issuer iam”jwks.issuers.iam missing or nested under hives: — it must be top-level
403 v2.requires_superadmin on plan applyBy design — use a superadmin token
Login works but /rest 401s in another serviceThat service lacks the jwks.issuers.iam entry, or its CPET headers don’t match the token’s tenant claim