Add admin impersonation console to the dashboard - #1321
Open
Sharqiewicz wants to merge 15 commits into
Open
Conversation
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vortexfi ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vrtx-dashboard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a high-risk admin impersonation console across the API and dashboard; despite the title, subaccounts remain deferred.
Changes:
- Adds role-gated impersonation sessions and principal substitution.
- Adds dashboard account search, auditing, and “Log in as” flows.
- Adds migrations, tests, operational tooling, and security documentation.
Reviewed changes
Copilot reviewed 55 out of 56 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
docs/security-spec/RISK-REGISTER.md |
Records impersonation risk. |
docs/security-spec/README.md |
Indexes the new specification. |
docs/security-spec/01-auth/admin-impersonation.md |
Defines impersonation security controls. |
docs/security-spec/01-auth/admin-auth.md |
Separates both admin surfaces. |
docs/product-dashboard.md |
Documents operator UI behavior. |
docs/architecture-identity-model.md |
Documents principal substitution. |
apps/dashboard/src/types/bun-test.d.ts |
Declares Bun mocking types. |
apps/dashboard/src/stores/impersonation.store.ts |
Manages impersonation state. |
apps/dashboard/src/stores/impersonation.store.test.ts |
Tests session transitions. |
apps/dashboard/src/stores/auth.store.ts |
Exports account-state cleanup. |
apps/dashboard/src/services/auth.ts |
Stores impersonation credentials. |
apps/dashboard/src/services/auth.test.ts |
Tests token precedence. |
apps/dashboard/src/services/api/api-client.ts |
Sends impersonation bearer tokens. |
apps/dashboard/src/services/api/api-client.test.ts |
Tests impersonated requests. |
apps/dashboard/src/services/api/admin-console.service.ts |
Defines admin API client. |
apps/dashboard/src/routeTree.gen.ts |
Registers admin routes. |
apps/dashboard/src/routes/_app/admin.tsx |
Adds account search and audit UI. |
apps/dashboard/src/routes/_app/admin.$profileId.tsx |
Adds account details. |
apps/dashboard/src/routes/_app.tsx |
Mounts impersonation banner. |
apps/dashboard/src/hooks/useAdminConsole.ts |
Adds admin query hooks. |
apps/dashboard/src/components/layout/ImpersonationBanner.tsx |
Displays active-session warning. |
apps/dashboard/src/components/layout/AppSidebar.tsx |
Adds role-gated navigation. |
apps/dashboard/src/components/admin/ImpersonateDialog.tsx |
Confirms impersonation starts. |
apps/dashboard/src/components/admin/AdminAccountsTable.tsx |
Displays searchable accounts. |
apps/api/src/models/profileRole.model.ts |
Adds vortex_admin. |
apps/api/src/models/index.ts |
Registers session associations. |
apps/api/src/models/adminImpersonationSession.model.ts |
Models impersonation sessions. |
apps/api/src/database/migrations/060-create-admin-impersonation-sessions.ts |
Creates session storage. |
apps/api/src/database/migrations/059-allow-vortex-admin-profile-role.ts |
Extends role constraints. |
apps/api/src/config/vars.ts |
Adds the kill switch. |
apps/api/src/api/services/impersonation.service.ts |
Implements session lifecycle. |
apps/api/src/api/services/impersonation.service.test.ts |
Tests lifecycle invariants. |
apps/api/src/api/routes/v1/index.ts |
Mounts admin-console routes. |
apps/api/src/api/routes/v1/api-credentials.route.ts |
Blocks credential minting. |
apps/api/src/api/routes/v1/api-credentials.route.test.ts |
Tests credential blocking. |
apps/api/src/api/routes/v1/admin-console/impersonation.route.ts |
Defines session routes. |
apps/api/src/api/routes/v1/admin-console/admin-console.route.test.ts |
Tests admin-console authorization. |
apps/api/src/api/routes/v1/admin-console/accounts.route.ts |
Defines account routes. |
apps/api/src/api/observability/types.ts |
Adds impersonation operations. |
apps/api/src/api/observability/apiClientEvent.service.ts |
Adds operator attribution. |
apps/api/src/api/observability/apiClientEvent.service.test.ts |
Tests attribution metadata. |
apps/api/src/api/middlewares/vortexAdminAuth.ts |
Adds role authorization. |
apps/api/src/api/middlewares/vortexAdminAuth.test.ts |
Tests role authorization. |
apps/api/src/api/middlewares/supabaseAuth.ts |
Resolves substituted principals. |
apps/api/src/api/middlewares/supabaseAuth.impersonation.test.ts |
Tests Supabase impersonation. |
apps/api/src/api/middlewares/ownershipAuth.impersonation.test.ts |
Tests target ownership. |
apps/api/src/api/middlewares/dualAuth.ts |
Supports impersonation bearer tokens. |
apps/api/src/api/middlewares/bearerPrincipal.ts |
Centralizes bearer resolution. |
apps/api/src/api/middlewares/bearerPrincipal.test.ts |
Tests principal resolution. |
apps/api/src/api/controllers/admin/profileRoles.controller.ts |
Restricts HTTP role grants. |
apps/api/src/api/controllers/admin/profileRoles.controller.test.ts |
Tests role restrictions. |
apps/api/src/api/controllers/admin-console/impersonation.controller.ts |
Implements session endpoints. |
apps/api/src/api/controllers/admin-console/accounts.controller.ts |
Implements account queries. |
apps/api/scripts/grant-vortex-admin.ts |
Adds out-of-band role grant. |
apps/api/package.json |
Registers the grant command. |
apps/api/.env.example |
Documents the kill switch. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an operator-facing admin console and short-lived impersonation sessions for profiles holding the out-of-band
vortex_adminrole.The implementation keeps the operator's Supabase session separate, stores only a hash of the temporary impersonation token on the server, attributes impersonated API events to both the operator and target, prevents impersonation chaining and API-credential minting, and supports revocation, expiry, role-removal invalidation, and a global kill switch.
Current implementation
Security posture and agreed first-iteration scope
Important
The current branch resolves an impersonation token as the target profile with the target's full application permissions. This is not the intended final scope for the first production iteration.
The first iteration must provide a server-enforced read-only support mode. Hiding buttons in the dashboard is not an authorization boundary: the API must default-deny mutations while
req.impersonationis present and allow only an explicit set of support reads.Expected read-only capabilities include:
The impersonated principal must not be able to:
Required first-iteration follow-up
Additional hardening before production use
localStorage, preferably behind an HttpOnly secure cookie or backend-for-frontend session.Verification completed for the current implementation