Files
IdeA/.ideai/tickets/72/carnet.md
Blomios f965f64b07 chore(ideai): clôture de #72 (confiance reverse proxy)
#72 passé en `closed` : mergé dans `develop` via `ae01297`, vert hors sandbox,
branche supprimée. Carnet complété avec le périmètre livré et les arbitrages.

État `.ideai/` indépendant du code de #68, committé directement sur `develop`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 23:44:12 +02:00

4.2 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#72 3
kind agent_id
agent a6ced819-b893-4213-b003-9e9dc79b9641
1784236365445

Ticket #72 — Confiance reverse proxy : carnet de chantier

Statut : livré et mergé dans develop (7fbaa8e) le 2026-07-16. Commits : 75d1ce8 (code), 42804fc (doc), ae01297 (merge --no-ff). Branche supprimée.

Ce qui a été livré

  • trusted_proxies dans ServerConfig + flag CLI --trusted-proxy (répétable, IP ou CIDR).
  • Refus au démarrage d'un bind non-loopback distant sans proxy autorisé.
  • Guard runtime sur les trois surfaces — statique, /api/*, WebSocket : le peer_addr est vérifié avant toute lecture de header.
  • X-Forwarded-Proto: https obligatoire en mode proxy.
  • X-Forwarded-For n'autorise jamais rien — journalisé uniquement.
  • B0 : réconciliation du port effectif dans run_server (le chemin CLI standalone souffrait du même bug que l'embedded : origin_allowed comparait à http://127.0.0.1:0).
  • Diagnostics : UntrustedProxyPeer, ForwardedProtoRejected, ForwardedHostMismatch.

Ajustement en cours de route — le hard reject X-Forwarded-Host a été RETIRÉ

Cadré initialement comme un refus, il est devenu un warning de diagnostic. Raison (Architect) : redondant avec la vérification d'Origin en égalité stricte déjà appliquée à toutes les routes /api/*, et il cassait la configuration par défaut de nginx, qui n'envoie pas cet en-tête. Le vrai contrôle d'accès reste pairing/session + pair proxy autorisé. Gain trop faible pour la friction créée.

Le repli de lecture accepte X-Forwarded-Host, Forwarded host= ou Host.

Vérification réelle (Main, hors sandbox)

cargo test -p web-server66 passed / 0 failed. Re-vérifié sur develop après merge : 66 · 41 (backend) · 35 (app-tauri), 0 échec.

Comportement exercé sur un serveur réellement lancé, pas seulement en test :

  • proxy autorisé + X-Forwarded-Proto: https + host absent (= nginx par défaut) → passe le guard, forwardedHostMismatch en diagnostic.
  • host différent → passe également, warning seulement.
  • X-Forwarded-Proto absent → 403, message : « Configure the reverse proxy to send it; for nginx add: proxy_set_header X-Forwarded-Proto $scheme; ».

⚠️ Piège d'environnement — un faux vert s'est produit ici, deux fois

DevBackend et QA sont tous deux bloqués par EPERM sur TcpListener::bind. Un cargo test -p web-server sandboxé rend un vert qui ne prouve rien : sur #68 B1, un « 57 passed » sandboxé a masqué un vrai bug produit (port éphémère vs origin_allowed). Tout vert sur ce crate doit être produit hors sandbox. C'est consigné dans les messages de commit, pas seulement ici.

Revue de sécurité (Git, au-delà du vert)

Guard câblé sur les trois surfaces, aucune route qui y échappe. Le chemin de production propage le vrai pair (handle_tcp_connectionSome(peer_addr.ip())). Le repli peer_ip.unwrap_or(config.listen.ip()) n'est atteignable que depuis des appelants #[cfg(test)]. CIDR correct, y compris prefix == 0 (qui aurait débordé au shift sans traitement à part).

Changement de comportement ASSUMÉ

Le durcissement casse volontairement les configurations existantes : un bind non-loopback distant sans --trusted-proxy est désormais refusé au démarrage, avec un message qui dit quoi faire. Consigné dans l'historique git.

Origine du ticket

Trouvé par Git, pas par une revue d'architecture : c'est lui qui a établi que --trust-reverse-proxy n'avait aucun effet runtime — il n'était lu que pour exiger sa propre présence. La trilogie déclarait une topologie sécurisée sans jamais la garantir.

Point ouvert, remonté par Git — à arbitrer par l'utilisateur

#73 (TLS intégré) rendrait une partie de #72 obsolète. Si idea-serve termine lui-même TLS, la cérémonie proxy — --trusted-proxy, le guard, ces diagnostics — ne concerne plus que les déploiements qui gardent un proxy devant. Ce n'est pas du travail perdu (#72 corrige un vrai trou aujourd'hui, et B0 était un bug réel), mais l'ordre des deux mérite un regard.