feat(security): scope office-ui agent lists to the workspace (#95 part 2)#122
Merged
Merged
Conversation
After #25 made `GET /api/v1/agents` admin-only, the office-ui's 9 agent-list queries 403 for non-admin users (they only work in the dev compose, which runs SKIP_AUTH=true). Move them onto the documented workspace-scoped path. - New `useWorkspaceId()` hook resolves the current workspace via `GET /api/v1/workspaces/current` (member-accessible — NOT the admin-only cross-workspace `/workspaces` list). - All 9 agent-list queries now call `GET /api/v1/workspaces/:wsId/agents` with `enabled: !!workspaceId` and `workspaceId` in the query key: agents, agents/new, agents/[id], chat, chat/[conversationId], meetings, meetings/[id], projects, office. - Server: the workspace-scoped list now decorates each agent with its `model_provider` (shared `decorateAgentsWithProviders` helper, also used by the admin list) so the response shape is identical — several UI sites read `agent.model_provider.provider` and would crash on a bare row. (The per-row provider lookup is an N+1, #32 — unchanged behavior; batch when #32 lands.) Tests: +1 registry test locking the scoped route's provider decoration (118 green). office-ui + registry typecheck green. Note: #95 part 1 (admin-gating the cross-workspace list routes) was already complete — workspaces/orgs/providers/agents/conversations are gated and there is no bare `GET /api/v1/runtimes`. This PR is part 2 (the office-ui migration). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
Completes #95 — moves the office-ui agent-list queries off the now-admin-only cross-workspace
GET /agentsonto the workspace-scoped path, so non-admin users stop getting 403s.Part 1 of #95 (admin-gating the cross-workspace list routes) was already done in earlier phases —
workspaces/orgs/providers/agents/conversationsare all gated, and there is no bareGET /api/v1/runtimesroute. This PR is part 2.Changes
office-ui
useWorkspaceId()hook (src/hooks/useWorkspaceId.ts) resolves the current workspace viaGET /api/v1/workspaces/current— the member-accessible "current workspace" shortcut, not the admin-only cross-workspace/workspaceslist.GET /api/v1/workspaces/:wsId/agentswithworkspaceIdin the query key andenabled: !!workspaceId:agents,agents/new,agents/[id],chat,chat/[conversationId],meetings,meetings/[id],projects,office. Per-file variations preserved (.catch(() => []), ther.data?.agents ?? r.dataparse,refetchInterval).registry (server)
model_provider, via a shareddecorateAgentsWithProvidershelper also used by the admin list — so the two responses have the identical shape. This matters: several UI sites readagent.model_provider.providerand would crash on a bare row. (The per-row provider lookup is an N+1, tracked in [Quality][Medium] N+1 query onGET /api/v1/agents(provider lookup per row) (Q-M-6) #32 — behavior unchanged, batch when [Quality][Medium] N+1 query onGET /api/v1/agents(provider lookup per row) (Q-M-6) #32 lands.)Tests
model_providerdecoration. Full registry suite green (118); office-ui + registry typecheck green.SKIP_AUTH=true(mock admin), so both the old and new paths work there; this PR fixes the non-admin / production path.Related / not in scope
GET /conversations(e.g.meetings/page.tsx); migrating those onto a scoped conversations path is a natural follow-up in the same spirit but outside [Security] Admin-gate the remaining cross-workspace list routes; move office-ui off /agents #95's explicit part-2 list.🤖 Generated with Claude Code