docs: add docs/architecture.md with C4 contexts, Nx boundaries, and CI/CD pipeline #1

Merged
julien merged 2 commits from docs/architecture-diagrams into main 2026-05-01 00:45:23 +02:00
Showing only changes of commit 4b8d0789b1 - Show all commits
@@ -60,6 +60,37 @@ The SPA must never hold tokens — that is the BFF security pattern, recommended
## Decision Outcome
The end-to-end flow at a glance:
```mermaid
sequenceDiagram
autonumber
actor U as User (browser)
participant SPA as portal-shell
participant BFF as portal-bff
participant E as Microsoft Entra ID
participant R as Redis (session store)
U->>SPA: clicks "Sign in"
SPA->>BFF: GET /auth/login?returnTo=…
BFF->>BFF: generate state + nonce<br/>+ code_verifier + code_challenge
BFF-->>U: 302 → Entra /authorize<br/>(client_id, code_challenge, state, nonce, scope)
U->>E: authenticate<br/>(Conditional Access enforces MFA)
E-->>U: 302 → BFF /auth/callback?code&state
U->>BFF: GET /auth/callback?code&state
BFF->>BFF: verify state matches<br/>(CSRF defence on the OIDC roundtrip)
BFF->>E: POST /token<br/>(code + code_verifier + client_secret/cert)
E-->>BFF: id_token + access_token + refresh_token
BFF->>BFF: validate id_token<br/>(sig, iss in allowlist, aud, exp/nbf)<br/>+ sanity-check amr (ADR-0011)<br/>+ map audience claim → Audience enum
BFF->>R: SET session:{opaque_id}<br/>payload incl. tokens encrypted AES-256-GCM (ADR-0010)
BFF-->>U: 302 → returnTo<br/>+ Set-Cookie __Host-portal_session<br/>+ Set-Cookie __Host-portal_csrf
U->>SPA: render destination (cookies attached on subsequent calls)
```
The numbered steps line up with the prose below: library / flow / tokens / token validation / refresh / cookies / CSRF / routes / auth layer.
**Library.** `@azure/msal-node`, instance of `ConfidentialClientApplication`, configured with the multi-tenant authority and the tenant allowlist from ADR-0008. PKCE is used despite the confidential-client setup, per IETF current BCP.
**Flow.** OAuth 2.0 Authorization Code Flow with PKCE, executed entirely on the BFF. The SPA never sees `code`, `code_verifier`, or any token.