# 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 ».