Revoke a platform admin's access
Use this procedure when a Novalien staff member leaves the platform-admin roster — voluntary departure, role change out of on-call, or suspected compromise. Platform admin access spans every customer org (via scoped impersonation), so revocation is higher-stakes than revoking a normal user. This page covers the product-side revocation; adjacent systems (Slack, PagerDuty, VPN, 1Password) are listed because a platform admin with partial access is more dangerous than one with none.
Procedure
-
Get approval from at least one other platform admin. Paste the revocation request, the reason (departure/role-change/compromise), and the target email into
#novavms-platform-ops. Wait for an ack from another platform admin. Self-revocation is allowed only for the compromise case and still requires the ack before the disable call. -
Set
enabled=falseon the platform_users row. Under your own platform JWT:Terminal window curl -X PATCH https://novavms.novalien.com/api/v1/platform/users/<id> \-H "Authorization: Bearer $PLATFORM_JWT" \-H "Content-Type: application/json" \-d '{"enabled": false}'The endpoint is
PATCH /api/v1/platform/users/{id}with a body of{"enabled": false}(cloud/internal/platform/users_handler.go:45). There is no/disablesub-route and noreasonfield on the request — the audit trail is captured implicitly via thedisabled_attimestamp on the row. Self-disable is refused with403(users_handler.go:118-121) so the platform tier cannot be locked out by a single admin disabling themselves. Note: the PATCH handler does NOT yet cascade-revoke the target’s active impersonation sessions, despite what US-PLAT-2 implies — see GAP-9-09. Until that ships, manually invokePOST /api/v1/platform/end-impersonationfor each of the target’s active sessions, or rely on the 30-minute TTL.
- Rotate 2FA. Even with the account disabled, a leaked TOTP seed or hardware key should not persist. Use the admin-account console to clear the enrolled factors; the target cannot re-enrol because the account is disabled.
-
Remove from adjacent systems. All four in the same session:
- Slack: remove from
#novavms-incidents,#novavms-platform-ops, demote to single-channel guest or deactivate. - PagerDuty: remove from every on-call rotation and every escalation policy they appear in.
- VPN (Tailscale): tag their node
disabled, expire the node key. - 1Password: remove from the
novavms-platform-opsvault and the shared-secrets vault.
- Slack: remove from
-
Hand over on-call duties if the target was an active responder. See Hand over on-call — do this in the same session, not later.
-
Audit check. The
platform_audit_logwill NOT yet show aplatform.user_disabledrow — the PATCH handler does not emit an audit row today (GAP-9-09). To confirm the disable landed, querySELECT id, enabled, disabled_at FROM platform_users WHERE id = '<id>'directly. Any impersonation sessions you ended via step 2’s manualend-impersonationcalls will appear asplatform.impersonation_endedentries inplatform_audit_logand asactor_type='platform_admin_impersonating'rows in each target org’s audit log.
Common variations
- Suspected compromise, not clean departure: run this procedure first, then escalate to security. Do not wait for full forensic confirmation — revoke first, investigate after. The audit trail survives the disable.
- Temporary suspension (medical leave, investigation): use the same disable call. Re-enable when the suspension ends. The enrolled 2FA must be re-added, not restored — there is no partial-disable mode.
- Account owned the last
allow_platform_impersonationsession for an org mid-investigation: the disable revokes that session too. If Legal needs the impersonation to continue, a different platform admin must mint a fresh token before step 2.
Related
- Scoped impersonation — what you are revoking.
- Hand over on-call — the rotation-side companion to this page.
- Audit log investigation — if the reason for revocation is suspected misuse and you need the trail.