Skip to content

feat: admin-only profile switch to verify user policies - #66

Merged
venkateshsakamuri-lab merged 5 commits into
cursor/schema-policy-multischema-c497from
cursor/admin-profile-switch-c497
Aug 19, 2026
Merged

feat: admin-only profile switch to verify user policies#66
venkateshsakamuri-lab merged 5 commits into
cursor/schema-policy-multischema-c497from
cursor/admin-profile-switch-c497

Conversation

@venkateshsakamuri-lab

@venkateshsakamuri-lab venkateshsakamuri-lab commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Admins can switch into a sub-user profile from the top-right of the app to verify that connection ACLs, chat/editor policies, and role-gated navigation actually apply.

How it works

The admin JWT stays on the session. Starting a switch sets an httpOnly impersonate_user cookie. JwtAuthenticationFilter overlays the target user's principal so every access check (AccessControlService, policies, /auth/me) runs as that user.

The impersonation control plane (GET|POST|DELETE /api/admin/impersonate), logout, refresh, and MCP tokens are excluded from the overlay so the real admin can stop the switch and so CLI tokens cannot ride the cookie.

Guardrails

  • ADMIN only
  • Cannot switch into another admin, yourself, or a non-ACTIVE account
  • Logout clears the impersonation cookie
  • Audited as IMPERSONATION_STARTED / IMPERSONATION_STOPPED

UI

  • Top-right View as control, admin-only (hover helper popups removed — they blocked clicks)
  • While switched: dark banner Viewing as <user> with Exit
  • Nav, Settings, and connection visibility follow the target role/permissions
  • Docs sidebar item removed; old docs nav state lands on Agent
  • Client session state (query cache, selected connection) resets on switch and on exit

API

  • GET /api/admin/impersonate — candidates + current status
  • POST /api/admin/impersonate { userId } — start
  • DELETE /api/admin/impersonate — stop
  • GET /api/auth/me returns the effective user plus impersonating / impersonatorUsername

Stacked on #65 so policy enforcement can be verified by switching into marts-editor.

Native Agent tab (follow-up on this branch)

The Agent tab 503'd on native mvn spring-boot:run because .env still used Compose DNS (deepsql-agent:8788) and Vite had no nginx X-Remote-User stamp. scripts/start-backend.sh now remaps unresolvable Compose hosts to loopback, the agent container can reach a host-side backend via host.docker.internal, and Vite forwards the effective username (including impersonation) to the Agent API.

Agent answered table count on ACME ERP
Only ACME ERP Multi-Schema connection remains
agent_working_and_acme_connection.mp4

Profile switch walkthrough

Sidebar without Docs
Admin View as control
View as dropdown listing marts-editor
Viewing as marts-editor banner
Editor shows only marts tables while switched
admin_profile_switch_view_as_exit.mp4

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 5 commits August 18, 2026 12:09
Admins can view the product as a sub-user from the top-right control.
The admin JWT stays on the session; an httpOnly impersonation cookie
overlays the target principal so connection ACLs, chat/editor policies,
and role-gated nav apply as they would for that user.

Co-authored-by: Venkat SF <venkatesh.sakamuri@stayflexi.com>
The switch sat absolutely over the Agent header, so clicks hit the
section underneath. Put it in a dedicated top-right bar instead.

Co-authored-by: Venkat SF <venkatesh.sakamuri@stayflexi.com>
The Docs sidebar tab is no longer a product surface. Persisted docs
nav state now lands on Agent. Remove HelpTooltip wrappers from the
profile-switch CTAs so they no longer intercept clicks.

Co-authored-by: Venkat SF <venkatesh.sakamuri@stayflexi.com>
The Agent tab 503'd because native spring-boot:run sourced Compose DNS
(deepsql-agent:8788) which does not resolve on the host. Remap those
hosts to loopback in start-backend.sh, and let the agent container reach
a host-side Java backend via host.docker.internal.

Co-authored-by: Venkat SF <venkatesh.sakamuri@stayflexi.com>
Vite has no nginx auth_request, so the Agent tab 401'd on
profile/switch. Send X-Remote-User from /api/agent/session's username
(including impersonation) and replay it on SSE via the proxy.

Co-authored-by: Venkat SF <venkatesh.sakamuri@stayflexi.com>
@venkateshsakamuri-lab
venkateshsakamuri-lab marked this pull request as ready for review August 18, 2026 18:33
@venkateshsakamuri-lab
venkateshsakamuri-lab merged commit 1cf7eac into cursor/schema-policy-multischema-c497 Aug 19, 2026
5 of 6 checks passed
@venkateshsakamuri-lab
venkateshsakamuri-lab deleted the cursor/admin-profile-switch-c497 branch August 19, 2026 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants