Skip to main content

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/me endpoint 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_log with 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.