docs(adr-0025): promote to accepted + sync persona matrix with test tenant
CI / scan (pull_request) Failing after 2m31s
CI / commits (pull_request) Successful in 2m56s
CI / check (pull_request) Successful in 3m10s
CI / a11y (pull_request) Successful in 2m46s
Docs site / build (pull_request) Successful in 2m56s
CI / perf (pull_request) Successful in 7m6s

The test tenant (apfrd.onmicrosoft.com) has been provisioned with the
full role / user matrix. ADR-0025 was accepted as the implementation
reference; this commit aligns the document with what is actually in
place.

Changes:

- Frontmatter status: proposed -> accepted; date unchanged
  (decision was already final on 2026-05-20).
- Privilege catalogue: expanded from 1 to 4 entries. Portal.Auditor,
  Portal.SecurityOfficer and Portal.DPO were anticipated future
  entries; they are now provisioned in the test tenant alongside
  Portal.Admin and ride the catalogue while their consuming
  surfaces land in subsequent PRs.
- Test-tenant personas: rewritten from 10 to 19 entries so every
  one of the 24 functional-role groups carries at least one user
  (apf-role-partenaire remains intentionally empty as a placeholder
  per the existing rationale). The four privileges each have an
  assigned user.
- New 'Provisioned in the test tenant' subsection records the
  Entra app-role GUIDs (kept in-repo because they are stable IDs
  the implementation will reference; group GUIDs stay
  gitignored).
- README.md index: status row flipped to accepted.
- CLAUDE.md: roll-up extended from '0001 -> 0024 accepted' to
  '0001 -> 0025 accepted', Architecture list grows an
  'Authorization model' bullet.
This commit is contained in:
Julien Gautier
2026-05-23 17:36:55 +02:00
parent 82d4245ab7
commit 985b0cb5d3
3 changed files with 47 additions and 30 deletions
+2 -1
View File
@@ -53,13 +53,14 @@ The structural, security, observability, and quality choices are recorded as ADR
- **Documentation site:** `docs/**/*.md` rendered as a separate static site via **VitePress** (Vite-based, Node-only toolchain, Markdown-first). Mermaid diagrams via `vitepress-plugin-mermaid`. Deployed on its own hostname behind the shared reverse-proxy; CI hook on `docs/` changes rebuilds + publishes. Decoupled from the apps — content lives in `docs/`, no in-app Markdown viewer — see [ADR-0022](docs/decisions/0022-docs-site-vitepress.md).
- **Charts + dashboards:** `D3 + Observable Plot` wrapped in `libs/shared/charts/`, one Angular component per chart type (bar, donut, line, stacked-bar, …). A11y baked in by the lib (SVG `<title>`/`<desc>`, `<details>` tabular fallback, colour-blind-safe palettes, AA-contrast text, `prefers-reduced-motion` gate). Bundle stays under [ADR-0017](docs/decisions/0017-performance-budgets-lighthouse-ci.md)'s lazy-chunk cap via per-`d3-*` module tree-shaking. Future bespoke visualisations land in raw D3 inside the same lib — see [ADR-0023](docs/decisions/0023-charts-d3-observable-plot.md).
- **AI service relay:** dedicated `apf-ai-service` repo (ASP.NET Core, Microsoft Agent Framework) consumed via native gRPC HTTP/2 only — proto contract vendored under `apps/portal-bff/src/grpc/proto/apf-ai/` with `ts-proto` codegen committed alongside. BFF dials with `@grpc/grpc-js` (h2c in dev, h2 + TLS in prod), bridges `ChatService.Chat` to `text/event-stream` for the SPA, exposes `RagService.Search` and `ModelsService.ListModels` as plain JSON endpoints. Identity travels as an unsigned `Principal` (subject, roles, attributes) in the proto body for the POC, hashed via the audit module's `HashUserIdService` so portal and AI service audit trails join on the same `actor_id_hash`. Production hardening (signed envelope vs mTLS) deferred — see [ADR-0024](docs/decisions/0024-ai-service-relay-grpc-sse-bridge.md).
- **Authorization model:** three orthogonal axes — **privileges** (Entra app roles, `Portal.*`), **functional roles** (Entra security groups → curated `apf-role-*` slug catalogue, 24 entries v1), **scopes** (portal-side `user_scopes` table, future Pléiades feed; kinds = `self / etablissement:<finess> / delegation:<dept> / region:<insee> / siege / unrestricted`). Composed at sign-in into a session-resident `Principal`; portal guards consume the structured shape, a deterministic `PrincipalProjector` flattens it to the AI-service `roles[]` contract. Replaces stargate's linear hierarchy. Catalogues are closed-set, drift gated by CI — see [ADR-0025](docs/decisions/0025-authorization-model-privileges-roles-scopes.md).
- **Runtime:** Node.js latest LTS major.
## Repository status
The Nx workspace is **scaffolded and operational**. The three apps (`portal-shell`, `portal-admin`, `portal-bff`) and the four lib roots (`libs/feature/`, `libs/shared/state`, `libs/shared/tokens`, `libs/shared/ui`, `libs/shared/util`) are in place; CI runs `format:check / lint / test / build` on every PR.
ADRs 0001 → 0024 are accepted and cover the structural, security, observability, quality, i18n, admin-app, docs-site, charts, and AI-relay choices. **Shipped on `main`:**
ADRs 0001 → 0025 are accepted and cover the structural, security, observability, quality, i18n, admin-app, docs-site, charts, AI-relay, and authorization choices. **Shipped on `main`:**
- **Phase-1 foundation** — Nx workspace, Angular `portal-shell`, NestJS `portal-bff`, Prisma + Postgres, Pino + OpenTelemetry, Husky/lint-staged/commitlint, Gitea Actions CI.
- **Phase-2 auth + audit + security** — OIDC Auth Code + PKCE via MSAL Node, Redis sessions with AES-256-GCM at rest, idle 30 min sliding + absolute 12 h hard ceiling, RP-initiated logout, double-submit CSRF, `audit.events` append-only schema with role-based grants, helmet + env-driven CORS allowlist + rate limiting + structured error envelope (see [ADR-0021](docs/decisions/0021-phase-2-security-baseline.md)).