feat(admin): add superadmin and session viewer permissions#4564
Conversation
75ab77b to
b4ca7f6
Compare
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Executive SummaryA malformed statement-breakpoint marker in the new migration and a stale-cache inconsistency in Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (27 files)
Fix these issues in Kilo Cloud Previous Review Summaries (2 snapshots, latest commit 79a79d2)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 79a79d2)Status: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up commit fixes the previously flagged transient-copy issue by gating the neutral "Checking your permissions…" message on Files Reviewed (1 file)
Previous review (commit 4dc9a81)Status: 1 Issue Found | Recommendation: Address before merge Executive SummaryA transient UI-copy issue in Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (25 files)
(Generated migration metadata files Reviewed by claude-sonnet-5 · Input: 66 · Output: 28.8K · Cached: 2.4M Review guidance: REVIEW.md from base branch |
| ); | ||
| } | ||
|
|
||
| async function assertNotLastUnblockedSuperadmin( |
There was a problem hiding this comment.
Low, Design: assertNotLastUnblockedSuperadmin protects the revoke and setAdminPermissions paths, but two other paths can drive the unblocked-superadmin count to zero without hitting this guard: blocking the last superadmin (sets blocked_reason, which the count filters on via isNull(blocked_reason)), and soft-deleting the last superadmin (clears is_super_admin). If the count reaches zero, no one can grant superadmin through /admin/admins, since every management procedure requires an unblocked superadmin, and recovery requires direct database access.
Likelihood is low given multiple staff were backfilled, and it is recoverable, so this is not a blocker. Consider extending the same guard to the block-user and soft-delete flows, or accepting it as a known operational edge case.
79a79d2 to
403187a
Compare
Summary
Adds explicit Superadmin and Session viewer capabilities beneath the existing platform-admin role.
The database migration adds
is_super_adminandcan_view_sessionsand enforces that subordinate permissions require platform-admin access. The superadmin backfill preserves the previous grant-authority boundary: it promotes only existing admins whose hosted domain is exactlykilocode.aiand whose email ends exactly in@kilocode.ai. Other existing admins and all non-admins remain non-superadmins, andcan_view_sessionsremainsfalsefor every existing user.Architecturally, sensitive authorization now uses primary-database permission revalidation instead of cached session claims. Superadmins can manage platform-admin membership, Session viewer, Superadmin, and Credit manager permissions from
/admin/admins. Permission changes are atomic, rotate active credentials, record attributed admin notes, and serialize only operations that reduce superadmin membership. All Session Traces procedures and in-product links now fail closed without Session viewer access. Successful permission data remains visible during background refetches so admin controls and loaded Session Traces do not reset on window focus.Verification
/admin/adminsand verified the admin roster displays permission badges and the Manage dialog exposes Superadmin, Session viewer, and Credit manager controls plus the separate revoke-admin action.Visual Changes
Reviewer Notes
The migration backfill mirrors the former
isEligibleForPlatformAdminpredicate:is_admin = true,hosted_domain = 'kilocode.ai', and a case-sensitive@kilocode.aiemail suffix. Existing admins outside that boundary are not promoted. No existing user receives Session viewer access.Review the last-unblocked-superadmin safeguard and its narrowly scoped transaction advisory lock. Platform-admin revocation and soft deletion clear every subordinate capability. Changing permissions rotates both web and API credential peppers, so affected users must sign in again.