Architecture: Multi-Tenant Access
Architecture: Multi-Tenant Client Board Access
Decision
Option B — pal-enterprises proxy pattern. Clients access their project board through pal-enterprises, which fetches data from pal-e-docs internally and renders a read-only view. pal-e-docs remains an internal ops tool with no client-facing auth.
Decided: 2026-05-10. Spike: ldraney/pal-enterprises#13
Options Evaluated
Option A — pal-e-docs native scoping (rejected): Would require adding multi-tenant RBAC to pal-e-docs. The API has zero auth —
list_boards() returns all boards, list_board_items() has no scoping. Changes the fundamental nature of pal-e-docs from internal ops tool to client-facing platform. High effort, high risk, wrong separation of concerns.Option B — pal-enterprises proxy (selected): pal-enterprises already owns client auth (Keycloak OIDC). A new controller fetches board data via pal-e-docs API (internal, service-to-service), renders read-only view filtered to client's project. ~100 lines of Rails code, no changes to pal-e-docs. Lucas controls what clients see — can filter labels, hide ops-only items.
Option C — Hybrid (not needed): No advantage over pure proxy since pal-e-docs doesn't need client auth for any other reason.
Keycloak Mapping Strategy
- Add
project_sluguser attribute to client users in Keycloak (e.g.project_slug: "westside") - Configure a protocol mapper on the pal-enterprises OIDC client to include
project_slugin token claims - pal-enterprises reads the claim, fetches
list_board_items(board_slug: "board-{project_slug}") - Same attribute can gate Forgejo repo access later via Keycloak group/role mapping
Implementation Shape
- Keycloak: Add
project_sluguser attribute + OIDC protocol mapper - pal-enterprises:
ClientBoardController— reads claim, calls pal-e-docs API, renders read-only view - pal-enterprises: Board view template using existing CSS design system (columns, cards, status indicators)
- No write endpoints — pure display, no forms, no mutations
Follow-up ticket: ldraney/pal-enterprises#17
Read-Only Enforcement
- pal-enterprises only exposes GET routes for the board view
- pal-e-docs API calls are server-side only — client browser never contacts pal-e-docs
- No client-side JS that could be exploited to make write calls
Related
ldraney/pal-enterprises#13— spike that produced this decisionldraney/pal-enterprises#17— follow-up feature ticketldraney/pal-enterprises#9— owner dashboard (Lucas sees all clients)