CORS recherche : allowlist soeurs prod+dev explicites (fusion #68/#69) #44

Merged
bruno merged 2 commits from cors-recherche-alertes-68-69 into main 2026-10-28 14:25:28 -04:00
Owner

CORS recherche : allowlist sœurs prod+dev explicites (fusion #68/#69, chantier 1)

Ne pas merger sans le go du coordinateur ; aucune version bumpée, aucune issue fermée ou rouverte par cette PR (les issues Projets/fusion-trois-apps #68 et #69 restent les suites de validation, leur état est inchangé).

Matrice constatée par Bruno (2026-10-28 13:33 EDT, page /recherche)

Depuis TikTak : ObsiGate OK ; Flowdeck ÉCHEC ; Kanbante ÉCHEC. Depuis Kanbante : ObsiGate OK ; Flowdeck ÉCHEC ; TikTak ÉCHEC. Depuis Flowdeck : ObsiGate OK, Flowdeck OK (lui-même) ; TikTak ÉCHEC ; Kanbante ÉCHEC. Depuis ObsiGate : ObsiGate OK ; Flowdeck ÉCHEC ; TikTak OK ; Kanbante OK. Le message affiché est « Injoignable depuis cet hôte (CORS ou réseau) » (fetch sans statut : blocage CORS/CSP/réseau, pas un 401/403).

Audit (vérifié sur main, dans le code)

  • ObsiGate n'autorisait que l'environnement de sa configuration (backend.draco_config.urls_publiques() : explicite > dérivation par l'hôte de l'agent > défaut prod), plus l'environnement de l'hôte de la requête — jamais les deux à la fois. Une page de l'autre environnement voyait donc sa section refusée.
  • Même schéma mono-environnement chez les sœurs : TikTak (draco_urls(hote_depuis_requete)), Kanbante (resoudre_urls_draco), Flowdeck (draco_urls.toutes() configuration seule au moment du middleware CORS ; alertes via le CORSMiddleware global figé à l'import).
  • La CSP connect-src n'est PAS le verrou : la page /recherche d'ObsiGate et la CSP globale résolvent leurs sœurs depuis la même configuration que les bases injectées dans la page — et la discipline dev/prod interdit les noms prod dans une instance dev. Cette PR ne touche donc à aucune CSP.
  • Côté alertes (fusion #69) : ObsiGate n'a aucune source de notifications entrantes consultable (/api/notify/* = canaux d'envoi sortants admin) — il n'y a donc pas de CORS serveur à ouvrir côté ObsiGate ; le panneau lit les sœurs, dont le CORS est corrigé par leurs PR respectives. La politique same-origin explicite du CORSMiddleware global (allow_origins=[]) reste la règle par défaut pour tout le reste.
  • Le cross-origin authentifié fonctionne en principe (depuis ObsiGate, TikTak et Kanbante répondent) : aucun repli serveur (proxy fan-out) n'est implémenté, conformément au chantier.
  • Ce que le code ne permet pas de conclure (à valider déployé) : la configuration réelle déclarée par chaque instance (.env dev/prod), et un éventuel filtre Cloudflare Access devant une instance — invisibles dans le code.

Ce qui change (ObsiGate)

  • backend/recherche_cors.py : sister_origins() retourne désormais les origines résolues plus PROD_ORIGINS | DEV_ORIGINS — les 8 origines officielles (og, flowdeck, tiktak, kanbante, avec et sans -dev, en https://*.dracodev.net), listées explicitement, jamais *, avec Access-Control-Allow-Credentials: true. Une origine inconnue reste refusée. Le paramètre request_host est conservé pour compatibilité mais ne restreint plus l'allowlist.
  • Tests : tests/test_recherche_cors.py (allowlist = 8 origines quelle que soit la résolution ; autre environnement autorisé ; tiers et sosie refusés).
  • Non touchés : pages /recherche et alertes, ligne d'onglets de la barre, CSP, CORSMiddleware global, versions, état des issues.

Tests (chiffres réels, exécutés le 2026-10-28)

  • Module backend/recherche_cors.py chargé par chemin + middleware ASGI simulé : 8 origines, preflight prod 204 / dev 204 / tiers transmis sans en-tête — OK.
  • Fichier tests/test_recherche_cors.py rejoué hors pytest (pytest absent de la sandbox) : 6 tests OK (dont les cas mis à jour).
  • python3 -m py_compile sur backend/recherche_cors.py, tests/test_recherche_cors.py : OK (et backend/main.py vérifié inchangé).
  • Non exécutés ici (dépendances applicatives absentes de la sandbox) : pytest tests/test_recherche_cors.py et le serveur — à valider en CI / après déploiement.

Validation déployée restante (par Bruno)

Matrice 4 hôtes × 4 sections sur /recherche (dev et prod) + panneau Alertes unifiées depuis chaque hôte : chaque section sœur doit afficher des résultats (ou « vide »), plus jamais « Injoignable ». Cas négatif à garder : une origine tierce ne doit toujours recevoir aucun en-tête Access-Control-Allow-Origin.

## CORS recherche : allowlist sœurs prod+dev explicites (fusion #68/#69, chantier 1) Ne pas merger sans le go du coordinateur ; aucune version bumpée, aucune issue fermée ou rouverte par cette PR (les issues Projets/fusion-trois-apps #68 et #69 restent les suites de validation, leur état est inchangé). ### Matrice constatée par Bruno (2026-10-28 13:33 EDT, page /recherche) Depuis TikTak : ObsiGate OK ; Flowdeck ÉCHEC ; Kanbante ÉCHEC. Depuis Kanbante : ObsiGate OK ; Flowdeck ÉCHEC ; TikTak ÉCHEC. Depuis Flowdeck : ObsiGate OK, Flowdeck OK (lui-même) ; TikTak ÉCHEC ; Kanbante ÉCHEC. Depuis ObsiGate : ObsiGate OK ; Flowdeck ÉCHEC ; TikTak OK ; Kanbante OK. Le message affiché est « Injoignable depuis cet hôte (CORS ou réseau) » (fetch sans statut : blocage CORS/CSP/réseau, pas un 401/403). ### Audit (vérifié sur main, dans le code) - ObsiGate n'autorisait que l'environnement de sa configuration (`backend.draco_config.urls_publiques()` : explicite > dérivation par l'hôte de l'agent > défaut prod), plus l'environnement de l'hôte de la requête — jamais les deux à la fois. Une page de l'autre environnement voyait donc sa section refusée. - Même schéma mono-environnement chez les sœurs : TikTak (`draco_urls(hote_depuis_requete)`), Kanbante (`resoudre_urls_draco`), Flowdeck (`draco_urls.toutes()` configuration seule au moment du middleware CORS ; alertes via le `CORSMiddleware` global figé à l'import). - La CSP `connect-src` n'est PAS le verrou : la page `/recherche` d'ObsiGate et la CSP globale résolvent leurs sœurs depuis la même configuration que les bases injectées dans la page — et la discipline dev/prod interdit les noms prod dans une instance dev. Cette PR ne touche donc à aucune CSP. - Côté alertes (fusion #69) : ObsiGate n'a aucune source de notifications entrantes consultable (`/api/notify/*` = canaux d'envoi sortants admin) — il n'y a donc pas de CORS serveur à ouvrir côté ObsiGate ; le panneau lit les sœurs, dont le CORS est corrigé par leurs PR respectives. La politique same-origin explicite du `CORSMiddleware` global (`allow_origins=[]`) reste la règle par défaut pour tout le reste. - Le cross-origin authentifié fonctionne en principe (depuis ObsiGate, TikTak et Kanbante répondent) : aucun repli serveur (proxy fan-out) n'est implémenté, conformément au chantier. - Ce que le code ne permet pas de conclure (à valider déployé) : la configuration réelle déclarée par chaque instance (`.env` dev/prod), et un éventuel filtre Cloudflare Access devant une instance — invisibles dans le code. ### Ce qui change (ObsiGate) - `backend/recherche_cors.py` : `sister_origins()` retourne désormais les origines résolues **plus** `PROD_ORIGINS | DEV_ORIGINS` — les 8 origines officielles (`og`, `flowdeck`, `tiktak`, `kanbante`, avec et sans `-dev`, en `https://*.dracodev.net`), listées explicitement, jamais `*`, avec `Access-Control-Allow-Credentials: true`. Une origine inconnue reste refusée. Le paramètre `request_host` est conservé pour compatibilité mais ne restreint plus l'allowlist. - Tests : `tests/test_recherche_cors.py` (allowlist = 8 origines quelle que soit la résolution ; autre environnement autorisé ; tiers et sosie refusés). - Non touchés : pages `/recherche` et alertes, ligne d'onglets de la barre, CSP, `CORSMiddleware` global, versions, état des issues. ### Tests (chiffres réels, exécutés le 2026-10-28) - Module `backend/recherche_cors.py` chargé par chemin + middleware ASGI simulé : 8 origines, preflight prod 204 / dev 204 / tiers transmis sans en-tête — OK. - Fichier `tests/test_recherche_cors.py` rejoué hors pytest (pytest absent de la sandbox) : **6 tests OK** (dont les cas mis à jour). - `python3 -m py_compile` sur `backend/recherche_cors.py`, `tests/test_recherche_cors.py` : OK (et `backend/main.py` vérifié inchangé). - Non exécutés ici (dépendances applicatives absentes de la sandbox) : `pytest tests/test_recherche_cors.py` et le serveur — à valider en CI / après déploiement. ### Validation déployée restante (par Bruno) Matrice 4 hôtes × 4 sections sur `/recherche` (dev et prod) + panneau Alertes unifiées depuis chaque hôte : chaque section sœur doit afficher des résultats (ou « vide »), plus jamais « Injoignable ». Cas négatif à garder : une origine tierce ne doit toujours recevoir aucun en-tête `Access-Control-Allow-Origin`.
bruno added 2 commits 2026-10-28 13:46:54 -04:00
Tests CORS recherche : prod+dev autorises, tiers refuse
CI / lint (pull_request) Failing after 0s
CI / security (pull_request) Failing after 1s
CI / test (pull_request) Skipped
CI / build (pull_request) Skipped
CI / e2e (pull_request) Skipped
b9a7824b28
bruno merged commit 5b9fe5944b into main 2026-10-28 14:25:28 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Projets/ObsiGate#44