Skip to content

feat(security): scope office-ui agent lists to the workspace (#95 part 2)#122

Merged
PanoramicRum merged 1 commit into
mainfrom
phase-s-95-office-ui-scoped-agents
Jun 4, 2026
Merged

feat(security): scope office-ui agent lists to the workspace (#95 part 2)#122
PanoramicRum merged 1 commit into
mainfrom
phase-s-95-office-ui-scoped-agents

Conversation

@PanoramicRum

Copy link
Copy Markdown
Contributor

Summary

Completes #95 — moves the office-ui agent-list queries off the now-admin-only cross-workspace GET /agents onto 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 / conversations are all gated, and there is no bare GET /api/v1/runtimes route. This PR is part 2.

Changes

office-ui

  • New useWorkspaceId() hook (src/hooks/useWorkspaceId.ts) resolves the current workspace via GET /api/v1/workspaces/current — the member-accessible "current workspace" shortcut, not the admin-only cross-workspace /workspaces list.
  • All 9 agent-list queries now call GET /api/v1/workspaces/:wsId/agents with workspaceId in the query key and enabled: !!workspaceId: agents, agents/new, agents/[id], chat, chat/[conversationId], meetings, meetings/[id], projects, office. Per-file variations preserved (.catch(() => []), the r.data?.agents ?? r.data parse, refetchInterval).

registry (server)

Tests

  • +1 registry test locking in the scoped route's model_provider decoration. Full registry suite green (118); office-ui + registry typecheck green.
  • The dev compose runs 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

🤖 Generated with Claude Code

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>
@PanoramicRum PanoramicRum merged commit 1a1aac2 into main Jun 4, 2026
6 checks passed
@PanoramicRum PanoramicRum deleted the phase-s-95-office-ui-scoped-agents branch June 4, 2026 18:13
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.

1 participant