Aller au contenu

PD-19 — Confrontation Gate 5 v1

Contexte

Analyse contradictoire des 10 points de la review ChatGPT gov-factual face aux documents sources (plan, code contracts, spécification, tests).


Point 1 — Cache-Control conditionnel (Review : Majeur)

Énoncé

Le plan ne précise pas de mécanisme explicite pour appliquer Cache-Control: no-store uniquement sur les réponses sensibles.

Confrontation

Code contracts (security_headers_config.cacheControl) :

cacheControl:
  sensitiveRoutes:
    value: "no-store"
  routes:
    - "/auth/*"
    - "/users/me"
    - "401 responses"
    - "403 responses"

Verdict confrontation : - PARTIELLEMENT VALIDE — Le code contract définit les routes sensibles mais le plan (Phase 2) ne détaille pas le mécanisme d'application contextuelle. - Recommandation : Ajouter dans Phase 2 la logique de détection des réponses sensibles (path matching + status code).

Gravité maintenue : Majeur


Point 2 — HSTS conditionnel dev (Review : Majeur)

Énoncé

Le contrat ne explicite pas la règle conditionnelle HSTS en dev (uniquement si HTTPS).

Confrontation

Code contracts (security_headers_config.strictTransportSecurity) :

strictTransportSecurity:
  enabled:
    type: "conditional"
    condition: "env !== 'development' || process.env.HTTPS === 'true'"
  maxAge:
    values:
      development: 300
      production: 31536000
      test: 31536000

Verdict confrontation : - INVALIDE (faux positif) — Le code contract explicite clairement la condition HSTS et les valeurs par environnement. - La review n'a pas lu correctement le YAML lines 36-51.

Gravité révisée : Non applicable (faux positif)


Point 3 — CORS credentials et exposedHeaders (Review : Bloquant)

Énoncé

Le contrat CORS ne cite pas explicitement Access-Control-Allow-Credentials: true ni les en-têtes exposés.

Confrontation

Code contracts (cors_config) :

credentials:
  type: boolean
  value: true
  invariant: INV-03
exposedHeaders:
  type: "string[]"
  values:
    - "X-Correlation-Id"
    - "Retry-After"
  invariant: INV-03

Verdict confrontation : - INVALIDE (faux positif) — Les deux éléments sont explicitement présents dans le code contract (lines 117-122 et 113-118). - La review a fait une erreur de lecture.

Gravité révisée : Non applicable (faux positif)


Point 4 — Stratégie refus preflight (Review : Majeur)

Énoncé

Le plan ne détaille pas la stratégie de refus explicite des pré-vols non autorisés.

Confrontation

Code contracts (cors_middleware.use.behavior) :

- "Si non autorisé: n'ajoute AUCUN header CORS (INV-04)"

Plan (Phase 3) :

"Aucun indicateur CORS si origine non autorisée"

Verdict confrontation : - PARTIELLEMENT VALIDE — Le comportement de refus est décrit (pas de headers CORS) mais le statut HTTP exact n'est pas précisé (200 ? 403 ? 204 ?). - Recommandation : Clarifier que le preflight non autorisé reçoit un 200 OK sans headers CORS (comportement standard navigateur).

Gravité révisée : Mineur (clarification documentaire)


Point 5 — DIV-01-v2 action test (Review : Bloquant)

Énoncé

Le plan ne décrit pas d'action test explicite pour étendre TC-ERR-02 aux refus CORS et 429.

Confrontation

Plan (Phase 6 — §6.4) :

"DIV-01-v2 | Assertions headers sur 429/refus CORS | Tests E2E Phase 6"

Plan (Phase 6 — §2.5) :

Créer test/e2e/security-headers.e2e-spec.ts : TC-NOM-01, TC-NOM-02, TC-NOM-05, TC-ERR-02

Code contracts (test_assertions.security_headers) :

assertions:
  - "Headers présents sur 200, 404, 405, 429, 500"

Verdict confrontation : - PARTIELLEMENT VALIDE — L'assertion "429" est présente dans les code contracts, mais le plan Phase 6 ne liste pas explicitement l'extension de TC-ERR-02 pour inclure refus CORS. - Recommandation : Ajouter explicitement dans Phase 6 : "Étendre TC-ERR-02 : assertions security headers sur 429 et refus CORS".

Gravité révisée : Majeur (pas bloquant car l'intention est présente, mais la traçabilité est faible)


Point 6 — DIV-02-v2 test intégration (Review : Majeur)

Énoncé

La qualification "résolution IP proxy en test d'intégration" est citée sans tâche dédiée.

Confrontation

Plan (§6.4) :

"DIV-02-v2 | Documentation test intégration IP proxy | Plan §4 + tests"

Plan (§4) :

"Résout IP client (X-Forwarded-For si proxy de confiance, sinon IP directe)"

Verdict confrontation : - VALIDE — Le plan mentionne la résolution mais ne crée pas de tâche/phase spécifique pour documenter/valider le mécanisme de proxy de confiance. - Recommandation : Ajouter dans Phase 6 une tâche "Créer test d'intégration TC-INT-01 : validation X-Forwarded-For avec trusted proxies".

Gravité maintenue : Majeur


Point 7 — Risque Redis non mitigé (Review : Majeur)

Énoncé

Aucun mécanisme d'atténuation décrit pour indisponibilité Redis.

Confrontation

Plan (§6.2 Performance) :

"Redis atomique (INCR + EXPIRE en une commande)"

Spec (INV-06) :

Limitation s'applique à tous endpoints — pas de mention de fallback.

Verdict confrontation : - VALIDE — Le risque d'indisponibilité Redis n'est pas adressé. Cependant, l'architecture existante (RateLimitService) a déjà un mécanisme de gestion (le service existe et fonctionne). - Recommandation : Ajouter dans §6 un point "Stratégie indisponibilité Redis : fail-open (permettre les requêtes) ou fail-closed (429 par défaut) — à valider avec l'équipe".

Gravité révisée : Mineur (hors scope spécification, mais bonne pratique)


Point 8 — Schéma log incomplet (Review : Bloquant)

Énoncé

Le plan ne détaille pas la complétude du schéma de log ni la rétention 90 jours.

Confrontation

Code contracts (audit_log_service.new_events) :

- name: CORS_REJECTED
  fields:
    - timestamp (UTC ISO-8601)
    - correlationId
    - environment
    - origin
    - method
    - endpoint
    - reason
  invariant: INV-09

- name: RATE_LIMIT_EXCEEDED
  fields:
    - timestamp (UTC ISO-8601)
    - correlationId
    - environment
    - ipHash (SHA256)
    - endpoint
    - windowStart
    - count
    - limit
  invariant: INV-09

Verdict confrontation : - PARTIELLEMENT VALIDE — Les champs sont détaillés dans les code contracts (lignes 284-305) mais la rétention 90 jours n'est pas mentionnée. - Recommandation : La rétention est une configuration infrastructure (non code), mais devrait être documentée dans le plan ou les code contracts.

Gravité révisée : Mineur (rétention = config infra, pas code)


Point 9 — Confusion middleware/guards (Review : Mineur)

Énoncé

La chaîne inclut des guards qui ne sont pas des middlewares NestJS.

Confrontation

Plan (§4) :

[1. SecurityHeadersMiddleware] → ... → [5. JwtAuthGuard] → [6. Specific Rate Limit Guards]

Verdict confrontation : - VALIDE — Le schéma mélange middlewares (NestMiddleware) et guards (CanActivate), ce qui peut induire en erreur. - Recommandation : Clarifier que le diagramme montre le flux logique complet, pas uniquement les middlewares au sens NestJS.

Gravité confirmée : Mineur


Point 10 — Fail-fast détail (Review : Majeur)

Énoncé

Le plan ne précise pas le comportement fail-fast au bootstrap.

Confrontation

Plan (Phase 1) :

configService.validateSecurityConfig(); // Throws si invalide

Spec (ERR-05) :

"Le service ne doit pas démarrer en mode permissif implicite. Comportement attendu unique : échec explicite de démarrage (fail-fast)."

Verdict confrontation : - PARTIELLEMENT VALIDE — Le plan indique "Throws si invalide" mais ne détaille pas les conditions exactes ni le message d'erreur. - Recommandation : Ajouter dans Phase 1 : "Conditions fail-fast : CORS_ORIGINS vide/invalide, RATE_LIMIT_GLOBAL_MAX < 1, etc. Message : 'Security configuration invalid: '."

Gravité maintenue : Majeur


Synthèse de la confrontation

Point Review Confrontation Gravité finale
1 Majeur Partiellement valide Majeur
2 Majeur Faux positif Non applicable
3 Bloquant Faux positif Non applicable
4 Majeur Partiellement valide Mineur
5 Bloquant Partiellement valide Majeur
6 Majeur Valide Majeur
7 Majeur Valide (hors scope) Mineur
8 Bloquant Partiellement valide Mineur
9 Mineur Valide Mineur
10 Majeur Partiellement valide Majeur

Résultat consolidé : - Bloquant : 0 (2 faux positifs identifiés) - Majeur : 4 (Points 1, 5, 6, 10) - Mineur : 4 (Points 4, 7, 8, 9) - Non applicable : 2 (Points 2, 3)

Conclusion : La confrontation a réduit les 3 bloquants à 0 (2 faux positifs de lecture du code contracts). Il reste 4 majeurs qui concernent principalement des clarifications du plan. Le plan est globalement conforme mais nécessite des précisions sur les mécanismes d'application contextuelle et la traçabilité des réserves Gate 3.


Document produit par le workflow de gouvernance IA — Gate 5 v1 Phase 2 (Confrontation Claude mode factuel) Date : 2026-02-09