gigafibre-fsm/docs/design/adr-001-pomerium-vs-traefik.md
louispaulb 512c4a5f1b feat(ops): dispatch auto complet + perf Boîte/rapports + fix session
Planificateur « Suggérer » : 4 stratégies (smart / meilleurs d'abord / équilibré /
juste ce qu'il faut), compétences+niveaux par tech (édition inline), niveau requis
par compétence + par job, carte des tournées (1 couleur/tech, domicile→arrêts,
sélecteur de jour), fenêtre de dispatch auj.+demain (dates sélectionnées), règle
week-end + placeholder « en attente du quart », clustering + lasso + filtre-date
sur la carte, accès rapide « À assigner » (badge).

Boîte : liste /conversations allégée (45 Mo → ~1 Mo, 17×) + messages chargés à
l'ouverture. Rapports : cache SWR sur revenue-explorer (22×). Session : keep-alive
+ timeout fetch global + authFetch durci → fin des rechargements manuels.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 08:49:35 -04:00

137 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR-001 : Proxy de périphérie & autorisation — Pomerium vs Traefik
**Statut :** Proposé
**Date :** 2026-07-01
**Décideurs :** Louis (+ équipe dev)
**Contexte déclencheur :** volonté de remplacer Traefik par Pomerium pour centraliser la matrice d'autorisation (routes × utilisateur / claims / token) et fermer les trous d'auth connus.
---
## Contexte
**Stack actuelle (chaîne d'accès)**
- **Traefik** en périphérie : terminaison TLS + ACME Let's Encrypt + routage par hostname.
- **nginx par app** : proxy local + injection du jeton API serveur (ex. `/hub/``Authorization: Bearer`, `/api` ERPNext).
- **hub Node** : `HUB_GATE` + jeton same-origin (voir patchwork ci-dessous).
- **Authentik (staff)** `auth.targo.ca` — OIDC ; forward-auth déjà en place sur le desk ERPNext.
- **Authentik (client)** `id.gigafibre.ca` — SSO client, IdP distinct.
**Contraintes réelles (vécues, documentées)**
- **SNAT FortiGate** → les ACL par IP sont impossibles au niveau proxy. ⇒ l'autorisation DOIT être *identitaire*, pas réseau. (Argument pour un proxy identity-aware… mais Authentik le fournit déjà.)
- **Let's Encrypt HTTP-01 fragile** : le redirect HTTP de Traefik a déjà cassé le challenge (correctif override netplan). Toute solution ACME en HTTP-01 hérite de cette fragilité.
- **HA FortiGate** + hôtes à ressources limitées (caps stricts 2 cœurs par endroits).
- **Trous d'auth connus** : routes `/hub` ouvertes ; `/campaigns` a déjà été public (incident cartes-cadeaux) ; authz en 2 couches, non uniforme.
**Nature du trafic (déterminante)**
- **Machine-to-machine / webhooks non-interactifs** (la majorité du volume sensible) : SPA ops → `/hub` (Bearer same-origin), Twilio, Giftbit, n8n, cron legacy F → hub, portail client. **Aucun ne peut faire un login OIDC interactif.**
- **Humains / navigateur** : SPA ops, desk ERPNext, UI n8n, GUI GenieACS, admin Nextcloud, etc.
**Objectif visé :** centraliser la matrice d'autorisation (routes × utilisateur/claims/token), refermer les trous, idéalement en remplaçant Traefik.
---
## Faits Pomerium (vérifiés 2026-07 sur la doc officielle)
| Dimension | Réalité |
|---|---|
| Rôle | Reverse proxy *identity-aware* ; authz à chaque requête via IdP OIDC ; route plusieurs upstreams par hostname. |
| **TLS / ACME (Autocert)** | Let's Encrypt via **HTTP-01 (port 80) ou TLS-ALPN-01 (port 443) uniquement****DNS-01 non supporté, pas de wildcard**. Exige un *Autocert Directory* persistant partagé (fs / S3 / GCS). |
| **Policy (PPL)** | YAML **config-as-code** par route : `email` / `domain` / `groups` / `claims` / appareil / jour. **Policy Builder visuel = Enterprise.** |
| **Auth machine (service accounts)** | **Enterprise / Zero UNIQUEMENT.** Le client présente un JWT Pomerium en `Bearer`. **Indisponible en OSS.** |
| Directory sync (groupes/rôles ext.) | **Enterprise.** |
| Déploiement | 4 services (proxy / authenticate / authorize / **databroker**), all-in-one possible. **HA ⇒ databroker PostgreSQL** (in-memory = 1 instance ; file = 1 instance persistée). |
| Console / GUI de gestion (la « matrice ») | **Enterprise / Zero (commercial).** OSS = fichiers de config. |
| IdP | OIDC générique ⇒ **Authentik compatible** comme fournisseur. |
> Sources : pomerium.com/docs (autorisation, service-accounts, autocert, internals/architecture), github.com/pomerium/pomerium.
**Conséquence directe sur le souhait « matrice par token ou utilisateur » :**
- **par UTILISATEUR (humain, OIDC)** → faisable en **OSS** (PPL par route) *et* déjà couvrable par **Authentik forward-auth**.
- **par TOKEN (machine)** → la façon Pomerium = **service accounts = Enterprise/Zero (payant)**. En OSS, les tokens machine restent gérés **au hub (`HUB_GATE`)** — Pomerium ne centralise pas ça gratuitement.
- **UI de matrice gérable** → **Enterprise/Zero.**
---
## Options considérées
### Option A — Remplacer Traefik par Pomerium (OSS)
| Complexité | Coût licence | Effort migration | Risque |
|---|---|---|---|
| Élevée | 0 $ | Élevé | **Élevé** |
**Contre :**
- Reprendre **tout** le TLS/ACME : HTTP-01 (fragilité déjà vécue) **sans** échappatoire DNS-01/wildcard.
- Router **tout** le public + les webhooks : en OSS, impossible d'authentifier les tokens machine → ces routes restent **publiques + auth applicative** = statu quo (on n'y gagne rien).
- **HA impose PostgreSQL** (databroker) : statefulness + sauvegarde + 4 services sur des hôtes à 2 cœurs.
- On **reconstruit le edge** sans obtenir la matrice-par-token (qui est Enterprise).
**Pour :** SSO humain uniforme ; authz identitaire (utile vu l'impossibilité d'ACL IP au FGT).
**Non recommandé.**
### Option B — Cohabitation : Traefik au edge + Pomerium en couche authz (OSS)
| Complexité | Coût | Effort | Risque |
|---|---|---|---|
| Moyenne | 0 $ | Moyen | Moyen |
Traefik **garde** TLS/ACME/edge (éprouvé). Pomerium derrière, **devant les apps humaines**, applique PPL par identité. Le trafic machine/API continue par `HUB_GATE`. **Adoption incrémentale, une app à la fois.**
**Pour :** faible risque, l'essentiel de la valeur (SSO + PPL policy-as-code sur les apps humaines), pas de big-bang TLS.
**Contre :** 2 proxies à opérer ; databroker Pomerium (Postgres si HA) ; double hop.
### Option C — Pas de Pomerium : durcir l'existant (Authentik forward-auth + HUB_GATE)
| Complexité | Coût | Effort | Risque |
|---|---|---|---|
| Faible | 0 $ | **Faible** | **Faible** |
Étendre le **forward-auth Authentik** (middleware Traefik, déjà utilisé sur le desk ERPNext) à **toutes** les routes humaines encore ouvertes + fermer les `/hub` non gardées au `HUB_GATE`.
**Pour :** effort/risque minimal, 0 nouveau composant, referme les **vrais** trous connus. Authentik a ses propres policies/entitlements par application.
**Contre :** pas de policy-as-code par-claim façon PPL (autorisation plus grossière : authentifié/pas authentifié + policies Authentik).
### Option D — Pomerium Enterprise / Zero
| Complexité | Coût | Effort | Risque |
|---|---|---|---|
| Moyenne-élevée | **Licence $** | Moyen | Moyen |
Seulement si la **matrice gérable** (UI, par utilisateur **et** par token/service-account, directory sync) devient une exigence dure.
**Pour :** service accounts (machine), Policy Builder, directory sync, console.
**Contre :** coût ; console = dépendance de plus (ou control-plane **hébergé** = sessions/politiques chez le fournisseur).
---
## Analyse des compromis
- **« Par token » centralisé** est le cœur du souhait — et c'est précisément une capacité **Enterprise**. En OSS, garder l'auth API **au hub** est le pattern standard et correct ; ça n'a pas à monter dans le proxy.
- **« Par utilisateur »** est faisable partout : OSS Pomerium (PPL) **ou** Authentik forward-auth (qu'on utilise déjà).
- **TLS/ACME** : Traefik est en place, éprouvé, et gère déjà le HTTP-01 fragile ; Pomerium autocert = **même classe de fragilité, sans DNS-01**. ⇒ argument fort pour **garder Traefik au edge**.
- **FGT SNAT (pas d'ACL IP)** : pousse vers une authz **identitaire** — offerte par Pomerium **et** Authentik. Le besoin est réel mais **Authentik le couvre déjà**.
- **Ressources / HA** : Pomerium OSS en HA = + PostgreSQL + 4 services. Coût ops non nul sur hôtes contraints.
- **Différenciateur réel de Pomerium** (vs Authentik) : PPL **policy-as-code** par route/claim (GitOps), authz **continue par requête** (pas seulement au login), contexte (appareil/heure), et **JWT signé** transmis aux upstreams. C'est ce qui justifierait B — pas le remplacement de Traefik.
---
## Conséquences
- **Plus facile** (B ou C) : SSO humain uniforme devant les apps → referme le gros des trous d'accès navigateur.
- **Plus difficile** (si A) : tout le edge/TLS à re-stabiliser ; l'auth machine **toujours** pas centralisée sans Enterprise.
- **À revisiter quoi qu'il arrive** : l'auth API du hub reste au `HUB_GATE` ; les webhooks (Twilio/Giftbit) resteront des **routes publiques + vérification de signature applicative** (aucun proxy n'y change rien).
---
## Recommandation
1. **Court terme — Option C (faible risque, ~80 % de la valeur sécurité).** Forward-auth Authentik sur toutes les routes humaines encore ouvertes via Traefik + audit/fermeture des `/hub` non gardées au `HUB_GATE`. Referme les trous connus avec ce qu'on a déjà.
2. **Si on veut policy-as-code par-claim + un vrai edge identity-aware devant les apps — Option B.** Pomerium **en couche derrière Traefik**, adopté **app par app**, en commençant par une app humaine à faible trafic (ex. UI n8n ou GUI GenieACS) pour valider l'OIDC Authentik + PPL + le placement TLS **avant** d'élargir.
3. **Ne pas** faire A (remplacement total). **D (Enterprise)** seulement si une « matrice par token gérée » devient une exigence business chiffrée.
**En une phrase :** Pomerium est un bon outil pour l'*autorisation identitaire des apps humaines* (Option B), pas pour *remplacer Traefik* ni pour *centraliser les tokens machine en gratuit* — et l'essentiel du gain sécurité s'obtient d'abord sans lui (Option C).
---
## Actions
1. [ ] **Générer l'inventaire des routes** (host × public / humain / machine × auth actuelle) — c'est la vraie « matrice » d'aujourd'hui, base de toute décision. *(Dérivable des confs Traefik/nginx + routeur SPA + endpoints hub.)*
2. [ ] **Option C** : activer le middleware forward-auth Authentik sur les hosts humains encore ouverts ; fermer les `/hub` non gardées.
3. [ ] *(Optionnel B)* PoC Pomerium OSS **derrière** Traefik sur 1 app humaine + IdP Authentik + une policy PPL ; mesurer le coût ops (databroker, autocert placement).
4. [ ] **Décider D** uniquement avec un besoin chiffré « matrice par token gérée ».