Platform Admin
Platform admins manage domain allowlists, users, organizations, and memberships across the entire DriftWise instance. Day-to-day admin work happens in the web UI; this page covers the concepts behind it. For exact endpoint contracts, see the admin section of the API reference.
Who is a platform admin
Platform admins are identified by an is_platform_admin flag on the
user record, not by a separate login. Any authenticated user can check
their own status, but admin-only endpoints reject everyone else with
403 platform admin required.
The first user who logs in with an allowed email domain is automatically promoted to platform admin. This is the only way the flag gets set without an existing admin intervening — subsequent promotions require an existing admin to make them through the API.
Authentication model
- Admin endpoints require an OIDC JWT from Casdoor. API keys are rejected outright, regardless of scope, because admin actions (SSO config, role reassignment, user deletion) must be attributable to a specific human in the audit log.
- The
/admin/meendpoint is the single exception: any authenticated caller can hit it, and it's the endpoint the frontend uses after OIDC login to decide whether to render the admin UI. It also triggers the first-user auto-promote. - Admin operations are logged to
admin_audit_logwith the actor's user ID, so incident response can always answer "who did what, when."
Domain allowlist
The domain allowlist controls which email domains can authenticate at
all. Users whose email is on a non-allowed domain are blocked at login
with 403 before any handler runs. The auth layer caches the allowlist
for 30 seconds, so removing a domain doesn't immediately log out active
sessions — existing tokens keep working until the 30s TTL expires or
until revocation propagates across pods via the shared cache bus.
Domain validation: must contain a dot, no @ prefix, no protocol
scheme (http:///https://), no spaces. All domains are
server-side lowercased.
User management
Users are created on first OIDC login (via the upsert in
DBKeyMiddleware). The admin API exposes list and soft-delete.
Soft-deleting a user clears their is_platform_admin flag, sets
deleted_at, and prevents future logins — but leaves org
memberships intact. Restoring access means un-deleting the row at
the DB level; there's no API for that by design. You cannot soft-delete
yourself.
Revoked sessions propagate across backend pods within 30 seconds via the revocation store; the user's auth fails immediately on the handling pod.
Organization management
The admin org-create endpoint is distinct from the user-facing
POST /orgs: the admin route provisions an org without assigning the
caller as owner (operator flow), while the self-service route at
POST /orgs makes the caller the sole owner.
Use the admin route when provisioning orgs for other customers or setting up demo environments. Use the self-service route when the eventual owner is the one signing up.
New orgs start on the Free plan; billing plan changes happen via the Stripe Checkout flow, not the admin API.
Membership management
Memberships are (user, org, role) triples. Valid roles are owner,
admin, member, and viewer — enforced case-sensitively both in
the API and at the DB CHECK constraint.
Role changes are OIDC-only at both the admin route (any org) and
the org-scoped route (PATCH /orgs/:id/memberships/:membershipID/role,
owner-only). API keys cannot mint admins even if the key has a write
scope, because that would let a compromised key rotate roles without
touching the human-attributable audit surface.
Same-role PATCH requests are idempotent no-ops: they return 200 with
noop: true and do not write an audit row. Last-owner demotion is
rejected with 409 — an org must always have at least one owner.
Seat limits apply to membership creation. Free plans cap at 3 seats,
Team at 10 (with overage billing), Enterprise is unlimited. Exceeding
the limit returns 402 Payment Required with the canonical
PaymentRequiredResponse shape.
Audit log
Every security-sensitive mutation (role change, API key create/revoke,
cloud account register, SSO config change, member add/remove) writes
an entry to admin_audit_log. The chain is hash-linked — each row's
hash covers the previous row's hash — so tampering with any historical
entry breaks chain verification.
Two verify endpoints exist: one scoped to a single org (owner/admin,
plus API keys for CI-driven integrity checks) and one scoped to
platform-level events (platform admin only). Both accept an
expected_min_seq watermark parameter that closes the tail-truncation
gap the hash chain alone can't detect — a privileged deletion of the
latest N rows leaves the remaining rows internally consistent.
See Audit Logs for the full event catalog and verification details.
Federation info
The /api/v2/federation-info endpoint (platform-admin-only, path is
outside /admin/ but gated by the same middleware) returns the GCP
Workload Identity Federation configuration for external CI systems
that want to obtain short-lived credentials instead of storing
long-lived API keys. The server returns 503 if it wasn't booted
with federation config.
Endpoint reference
All admin endpoints are documented in the admin tag of the API reference. Audit log endpoints (both the listing and the integrity-verify routes) are under the audit tag.