Skip to content

Runbook — Superadmin access governance (ADR-0134 D2 / ADR-0136)

users.is_superadmin = 1 grants the staff console (/admin/**): payment activation, FinOps margins, incidents, and cross-tenant data (any tenant’s health, private conversations on the audited paths). It is the most powerful flag in the system. There is no self-serve UI to set it — by design.

The audit trail and the live holder list are at /admin/access.


Who approves: a current superadmin + the requester’s manager. Grant the minimum needed (today that’s full superadmin; a scoped billing_ops role is a follow-up — see ADR-0134).

Steps:

  1. Confirm the person has MFA enrolled (the console requires fresh MFA; an unenrolled superadmin is blocked anyway).
  2. Run the sanctioned script (from platform/) — it flips the flag and writes the audit event in one go (ADR-0136):
    Terminal window
    node scripts/superadmin-access.mjs \
    --env prod --email <email> --action grant \
    --by <your-email> --reason "<approval + who signed off>"
  3. Verify at /admin/access: the new holder appears with grant logged (not out-of-band) and the event shows in the access log.

Break-glass: a raw UPDATE users SET is_superadmin = 1 … still works, but it writes no audit event and will show as out-of-band drift at /admin/access. Prefer the script; reconcile any drift.

For someone who only fulfils payments, grant the least-privilege role instead of full superadmin — same script, add --role billing_ops:

Terminal window
node scripts/superadmin-access.mjs \
--env prod --email <email> --action grant --role billing_ops \
--by <your-email> --reason "payments fulfilment, approved by <manager>"

billing_ops can see the payment queue and Mark paid. It cannot open any tenant’s health, fleet margins, incidents, or this access page — those stay superadmin-only. (--role defaults to superadmin when omitted.) Revoke the same way with --action revoke --role billing_ops.

When someone leaves the staff role or no longer needs it — same script:

Terminal window
node scripts/superadmin-access.mjs \
--env prod --email <email> --action revoke \
--by <your-email> --reason "offboarding / no longer needed"

Revoke promptly on offboarding.

Quarterly, open /admin/access and confirm each current superadmin still needs it. Two checks:

  • Anyone who shouldn’t be there → revoke (script above).
  • Anyone flagged out-of-band (holds the flag with no grant event) → either re-grant via the script to capture who/why, or revoke. Record the review date + outcome.

A self-serve toggle for an account-wide, cross-tenant superpower is a privilege- escalation foot-gun. An operator-run script by an existing superadmin, with a recorded reason and a quarterly review, is the deliberate control (ADR-0134 D2 / ADR-0136) — the audit lives in user_security_events, not a web grant endpoint. The console itself is gated on this flag plus fresh MFA (/admin/+layout.server.ts), with the per-page guards retained as defense in depth.

Follow-up (ADR-0134): a scoped billing_ops capability for least-privilege.