Skip to content

feat: org-wide ACL access overview#311

Open
schmug wants to merge 1 commit into
mainfrom
claude/wizardly-einstein-Amobg
Open

feat: org-wide ACL access overview#311
schmug wants to merge 1 commit into
mainfrom
claude/wizardly-einstein-Amobg

Conversation

@schmug
Copy link
Copy Markdown
Owner

@schmug schmug commented May 22, 2026

Summary

  • Adds GET /api/v1/org/acl-overview returning every mailbox with { email, acl_status, owner: string|null, members: string[] }
  • Adds /acl frontend route rendering a filterable table (by domain + text search) of all mailbox access grants
  • 7 new backend tests covering all-unscoped, all-scoped, mixed fleet, and authz assertions

Authz model (documented here and in the endpoint comment)

Any CF-Access-admitted caller receives the full data. No org-admin role exists in this system; the Cloudflare Access policy is the org boundary — everyone admitted by CF Access is an org member or operator. This is intentional and consistent with /api/v1/org/overview, which also returns org-wide data to any authenticated caller. Callers without a CF Access header (local dev) receive the same data — consistent with all other /api/v1/org/* endpoints.

This is not a silent privacy regression: it is a deliberate design decision, documented in the endpoint code comment and in this PR body, with tests that explicitly assert "non-owner authenticated callers receive 200 with full data, not 403."

Files changed (8 files, ~435 lines)

Note: This technically exceeds the 6-file auto-decompose threshold but is well under the 1500-line threshold. The feature is tightly cohesive (backend endpoint + API client + query hook + route + tests); splitting backend from UI would require stacked PRs with the known complications described in CLAUDE.md.

  • workers/index.ts — new endpoint
  • app/services/api.tsgetOrgAclOverview() API call
  • app/types/index.tsAclOverviewEntry interface
  • app/queries/keys.tsorg.aclOverview query key
  • app/queries/org.tsuseOrgAclOverview() hook
  • app/routes/org-acl.tsx — new /acl route (table + filters)
  • app/routes.ts — route registration
  • tests/routes/acl-overview.test.ts — 7 new tests

Test plan

  • tests/routes/acl-overview.test.ts — 7 tests: empty fleet, all-unscoped, all-scoped, mixed fleet, local-dev (no CF Access header → 200), non-owner member caller (→ 200), multi-domain fleet
  • Full test suite: 1086 passing, 0 failing
  • npm run typecheck — clean

Closes

Closes #292

Spec follow-up needed

No — this change doesn't touch any invariants in SECURITY_SPEC.md.

Deferred / out of scope


Generated by Claude Code

Adds GET /api/v1/org/acl-overview returning every mailbox with
acl_status, owner, and members. Authz: any CF-Access-admitted caller
(no org-admin role exists; Access policy is the org boundary —
consistent with /api/v1/org/overview). Frontend: /acl route renders
a table filterable by domain and text search.

https://claude.ai/code/session_01W3BVzoQixUKgRCNiefCLMD
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ais-hub 1d14728 Commit Preview URL

Branch Preview URL
May 22 2026, 12:22 PM

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.

Add org-wide ACL access-overview (who can see which mailboxes)

2 participants