1 Commits

Author SHA1 Message Date
xarmian f48c99e421 fix(auth): scope admin platform role to cookie session auth (BUG-1616) (#632)
The admin platform role granted owner-level access to every workspace on
every surface, including bearer-borne callers (PATs on /api/v1, CLI
session bearers, PATs/OAuth on /mcp). A user with "All current
workspaces" consent on an MCP client — or a leaked admin token of any
kind — could reach data the admin never joined.

Policy: the admin global bypass now fires only for cookie session auth
(web UI / SPA / /console/admin). Bearer-borne callers fall back to a
strict workspace_members check (membership-only; no guest-grants
fallback either).

Gated four sites in lockstep:

- RequireWorkspaceAccess (internal/server/middleware_auth.go) — covers
  /api/v1/* routes; emits the existing not_a_member MCP authz denial
  metric on bearer-admin denials.
- handleSSE entry (internal/server/handlers_events.go) — adds an
  explicit GetWorkspaceMember check for bearer-borne admin after
  resolveWorkspace's global slug lookup.
- sseSubscriberStillHasAccess (internal/server/handlers_events.go) —
  per-tick revalidation now matches entry-time policy.
- computeSSEVisibility (internal/server/handlers_events.go) —
  bearer-admin gets a real VisibleCollectionIDs filter instead of
  "no filtering"; a bearer-admin who's a member with
  collection_access=specific is now correctly scoped.
- authorizeCollabAccess (internal/server/handlers_collab.go) —
  WebSocket collab upgrade gate; same membership-only stance.

New shared helper isBearerAuth(r) folds two signals (Authorization:
Bearer header OR ctxIsAPIToken stash) so MCP-dispatcher synthesized
requests and CLI session bearers are both covered. Mirrors the dual
check middleware_csrf.go already uses.

Tests (9 total):

- middleware_auth_admin_token_gate_test.go (5) — PAT denied/allowed
  permutations, CLI session-bearer denial, cookie-session bypass
  preserved.
- handlers_admin_bearer_gate_test.go (4) — SSE revalidation,
  visibility filter, collab WebSocket auth.

Companion BUG-1617 (store-layer admin bypass in backlinks visibility)
tracked separately.
2026-05-27 10:09:30 -04:00