Fuzzing derrière la porte, audit qui voit tout le pipeline, et un seul build Next par run #9

Closed
opened 2026-10-15 19:17:27 +00:00 by nicolas-fryder · 1 comment

Ce ticket fait suite à la lecture des journaux du run 27 d'ATLAS (chasse 53 du socle). Les corrections ponctuelles sont dans #8. Trois chantiers demandent une conception.

1. Le fuzzing ne teste que la porte

Sur ATLAS, 159 opérations sur 166 n'ont reçu que le 401 du proxy : environ 3 975 cas sur 4 006 se sont arrêtés à la porte. contract.yml n'a aucune entrée d'identité. Son en-tête promet « l'application tient-elle son propre contrat », mais 96 % du contrat n'est jamais atteint.

Piste.

  • Une entrée identite : le nom d'un script du satellite, lancé après la santé.
  • Ce script écrit EQS_FUZZ_BEARER et/ou EQS_FUZZ_SESSION dans $GITHUB_ENV, précédés de ::add-mask::.
  • Schemathesis s'authentifie selon le contrat ([auth.openapi.<schéma>] dans un schemathesis.toml), et non par un -H global : un Authorization posé sur une route session: true la ferait refuser.
  • Pour fabriquer l'identité, tout satellite @eqs/auth a un compte de secours (BREAK_GLASS_*). Le workflow pourrait les tirer au hasard comme il le fait pour AUTH_SECRET. Le socle pourrait fournir l'aide qui ouvre la session, et preparerCle donne une clé d'API.

Précautions.

  • Exclure les routes qui sortent sur le réseau (proxies WMS et tuiles, RNB, ingest…) et celles qui couperaient la session du fuzzeur (DELETE /api/profile/sessions).
  • Prévoir des 429.

Classe connexe. Une opération 3xx est jugée sur sa page finale, parce que schemathesis suit les redirections : c'est le faux positif sur /api/oauth/authorize. Il faut une parade, par exemple un hook ou une marque x-eqs-*.

2. L'audit envoyé à Topologie ne voit pas le pipeline

audit ne dépend que de check. Il part avant integration et contract. Au run 27, l'audit a été envoyé à 18:35 et le fuzzing du même commit a échoué à 18:40. Topologie a reçu un commit sain.

  • #8 apporte la durée de la porte (check-duree).
  • Il manque :
    • la conformité, écrite dans .eqs/conformance.json par le job integration, qui meurt avec lui. 7 champs partent null ;
    • le verdict des autres étages.

Piste.

  • integration.yml téléverse conformance.json.
  • audit passe en needs: [check, integration, contract] avec if: always(), et joint un verdict du pipeline.
  • Côté socle : écrire commit dans check.json et conformance.json, et refuser un rapport d'un autre commit.

3. Next est construit trois ou quatre fois par run

integration (dans la suite de conformité), contrat-a-jour (évitable dès #8 avec construire-contrat: false) et fuzzing construisent chacun Next, environ 2 min 10 s par build. Le runner ne fait qu'un job à la fois, donc tout se paie en série.

Piste. Publier .next (sans cache/) comme artefact du job qui construit, et le télécharger ailleurs. À défaut, mettre .next/cache en cache.

Moins urgent

  • Préinstaller semgrep et schemathesis dans l'image du runner : environ 40 s par run.
  • Mettre en cache COREPACK_HOME.
  • git config --system init.defaultBranch main dans l'image.

🤖 Generated with Claude Code

Ce ticket fait suite à la lecture des journaux du run 27 d'ATLAS (chasse 53 du socle). Les corrections ponctuelles sont dans #8. Trois chantiers demandent une conception. ## 1. Le fuzzing ne teste que la porte Sur ATLAS, **159 opérations sur 166** n'ont reçu que le 401 du proxy : environ 3 975 cas sur 4 006 se sont arrêtés à la porte. `contract.yml` n'a aucune entrée d'identité. Son en-tête promet « l'application tient-elle son propre contrat », mais 96 % du contrat n'est jamais atteint. **Piste.** - Une entrée `identite` : le nom d'un script du satellite, lancé après la santé. - Ce script écrit `EQS_FUZZ_BEARER` et/ou `EQS_FUZZ_SESSION` dans `$GITHUB_ENV`, précédés de `::add-mask::`. - Schemathesis s'authentifie selon le contrat (`[auth.openapi.<schéma>]` dans un `schemathesis.toml`), et non par un `-H` global : un `Authorization` posé sur une route `session: true` la ferait refuser. - Pour fabriquer l'identité, tout satellite `@eqs/auth` a un compte de secours (`BREAK_GLASS_*`). Le workflow pourrait les tirer au hasard comme il le fait pour `AUTH_SECRET`. Le socle pourrait fournir l'aide qui ouvre la session, et `preparerCle` donne une clé d'API. **Précautions.** - Exclure les routes qui sortent sur le réseau (proxies WMS et tuiles, RNB, ingest…) et celles qui couperaient la session du fuzzeur (`DELETE /api/profile/sessions`). - Prévoir des 429. **Classe connexe.** Une opération 3xx est jugée sur sa page finale, parce que schemathesis suit les redirections : c'est le faux positif sur `/api/oauth/authorize`. Il faut une parade, par exemple un hook ou une marque `x-eqs-*`. ## 2. L'audit envoyé à Topologie ne voit pas le pipeline `audit` ne dépend que de `check`. Il part avant `integration` et `contract`. Au run 27, l'audit a été envoyé à 18:35 et le fuzzing du même commit a échoué à 18:40. Topologie a reçu un commit sain. - #8 apporte la durée de la porte (`check-duree`). - Il manque : - la conformité, écrite dans `.eqs/conformance.json` par le job integration, qui meurt avec lui. 7 champs partent `null` ; - le verdict des autres étages. **Piste.** - `integration.yml` téléverse `conformance.json`. - `audit` passe en `needs: [check, integration, contract]` avec `if: always()`, et joint un verdict du pipeline. - Côté socle : écrire `commit` dans `check.json` et `conformance.json`, et refuser un rapport d'un autre commit. ## 3. Next est construit trois ou quatre fois par run `integration` (dans la suite de conformité), `contrat-a-jour` (évitable dès #8 avec `construire-contrat: false`) et `fuzzing` construisent chacun Next, environ 2 min 10 s par build. Le runner ne fait qu'un job à la fois, donc tout se paie en série. **Piste.** Publier `.next` (sans `cache/`) comme artefact du job qui construit, et le télécharger ailleurs. À défaut, mettre `.next/cache` en cache. ## Moins urgent - Préinstaller semgrep et schemathesis dans l'image du runner : environ 40 s par run. - Mettre en cache `COREPACK_HOME`. - `git config --system init.defaultBranch main` dans l'image. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Owner

Les trois chantiers sont livrés.

  1. Le fuzzing passe la porte (v1.7) : l'entrée identite lance un script du satellite, qui crée eqs-ci (admin, une clé d'API) dans la base jetable du fuzzing ; la clé est masquée et passée à schemathesis. Les refus métier 422 documentés sont acceptés pour des données valides ; un 400 reste une faute.
    • Démo : 212 cas, 212 passés.
    • ATLAS (96 chemins sur 133) : 4 vrais défauts trouvés dès le premier passage, dont un serveur qui tombe, suivis dans EQS/ATLAS#13.
  2. L'audit voit le pipeline (v1.6, pipeline.yml, D-084) : il part après l'intégration et le fuzzing, dans le même job, avec la durée de la porte et la conformité du run. Chez ATLAS, il reste 3 champs non observés au lieu de 10.
  3. Un seul build Next par job (v1.6) : l'intégration et le fuzzing réutilisent le build du job application, et le cache de compilation Next survit d'un run à l'autre. Chez ATLAS, la compilation passe de 84 s à 11 s, et le pipeline complet d'environ 25 min à 15 min.

Aussi : un cache pip pour semgrep et schemathesis, et le store pnpm dans .git (liens au lieu de copies).

Pas fait, et pas nécessaire aujourd'hui :

  • joindre un verdict du pipeline à l'audit (champ de schéma) ;
  • mettre en cache COREPACK_HOME (environ 2 s) ;
  • init.defaultBranch dans l'image du runner (pur bruit de journal).

🤖 Generated with Claude Code

Les trois chantiers sont livrés. 1. **Le fuzzing passe la porte** (v1.7) : l'entrée `identite` lance un script du satellite, qui crée `eqs-ci` (admin, une clé d'API) dans la base jetable du fuzzing ; la clé est masquée et passée à schemathesis. Les refus métier 422 documentés sont acceptés pour des données valides ; un 400 reste une faute. - Démo : 212 cas, 212 passés. - ATLAS (96 chemins sur 133) : 4 vrais défauts trouvés dès le premier passage, dont un serveur qui tombe, suivis dans EQS/ATLAS#13. 2. **L'audit voit le pipeline** (v1.6, `pipeline.yml`, D-084) : il part après l'intégration et le fuzzing, dans le même job, avec la durée de la porte et la conformité du run. Chez ATLAS, il reste 3 champs non observés au lieu de 10. 3. **Un seul build Next par job** (v1.6) : l'intégration et le fuzzing réutilisent le build du job `application`, et le cache de compilation Next survit d'un run à l'autre. Chez ATLAS, la compilation passe de 84 s à 11 s, et le pipeline complet d'environ 25 min à 15 min. Aussi : un cache pip pour semgrep et schemathesis, et le store pnpm dans `.git` (liens au lieu de copies). Pas fait, et pas nécessaire aujourd'hui : - joindre un verdict du pipeline à l'audit (champ de schéma) ; - mettre en cache `COREPACK_HOME` (environ 2 s) ; - `init.defaultBranch` dans l'image du runner (pur bruit de journal). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Infrastructure/eqs-workflows#9
No description provided.