Skip to content

feat(auth): refuse observers every endpoint that changes the organization - #2546

Open
Makisuo wants to merge 1 commit into
observer/policyfrom
observer/enforcement
Open

Makisuo wants to merge 1 commit into
observer/policyfrom
observer/enforcement

feat(auth): refuse observers every endpoint that changes the organiza…

11938f4
Select commit
Loading
Failed to load commit list.
Maple Review Bot / Maple / review succeeded Nov 12, 2026 in 3m 16s

Confidence 8/10 · No issues found

🟢 Confidence 8/10 · likely safe to merge. Fail-closed gate with readable markers; the internal and public middleware wiring has no end-to-end observer test, only the gate functions.
no findings · tests partial −1 · risk high −1

Refuses a read-only role every non-GET endpoint the internal, public and /v2 auth middlewares serve, unless the endpoint (or its group) is marked ObserverAccess or /v2 already names the route a read. The markers match what those handlers change, and the default is refuse.

  • refuseObserverWrites fails 403 ReadOnlyRoleError in the internal and public auth layers
  • refuseObserverWritesV2 reuses the /v2 scope registry's read-only POST list
  • ObserverAccess marks the six query groups plus the caller's own devices and approvals
  • Endpoint-level read marks cover digest, billing, integrations and the escalation dry run

Before merge

  • Manual · Verify every Clerk role key in dev and prd is known to roleOf; an unknown key reads as observer

Production impact

Production traffic of the changed files (last 7 days)
File Calls/day Busiest operations
packages/domain/src/http/observer-access.ts 562 GET 306/day, 0.3% err
GET 256/day, 3.0% err
packages/domain/src/http/digest.ts 53 preview 53/day, 1.1% err
packages/domain/src/http/v2/device-credentials.ts 49 POST /v2/device_tokens 49/day, 0.0% err
What was checked
  • UserSessionAuthorization left ungated: it serves only organization creation (organizations.ts:126)
  • Device-credential revoke is user-scoped (tenant.userId); MCP revoke passes viewer (mcp-connections.http.ts:47)
  • Every POST in the group-marked queryEngine, users, mcp, aiSessions, sessionReplays, aiModels groups is a query

11938f4 · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.