Repository navigation
feat(ci,#13378): tranche 2 — self-hosted job trigger allowlist fail-closed (#14201) - #14242
Conversation
…losed Le denylist de #14148 (FORK_REACHABLE_TRIGGERS) est fail-OPEN sur tout trigger non enumere (check_run/check_suite portent pull_requests[] et un head_sha, un futur evenement GitHub peut faire de meme). Remplace par un allowlist default-deny des triggers surs (pull_request, push, schedule, workflow_dispatch) : tout trigger hors de l'ensemble (et hors des connus-dangereux codes specifiques PULL_REQUEST_TARGET/WORKFLOW_RUN/ REUSABLE_SELF_HOSTED/FORK_REACHABLE_TRIGGER) est rejete par defaut. push/schedule/workflow_dispatch restent acceptes : ils ne portent que des refs du depot, la branche == null de la garde universelle y est sure par construction (mesure sur banner-guard/hooks-parity, dont le contre-controle est dans #14148). Controle positif : scan du depot reel -> ok=True, self_hosted=14, 0 violation (les 11 workflows routes par #14148 + les 3 pre-existants passent). Mutation verifiee (allowlist neutralisee -> UNSAFE_TRIGGER disparait). 48 tests verts (45 existants preserves + 3 nouveaux). Co-Authored-By: Claude-Code <noreply@anthropic.com>
|
G-VAR-2 light cap reached (advisory, non bloquant). |
Bash Syntax Advisory — shebang / executable-bit warningsSee the |
jsboige
left a comment
There was a problem hiding this comment.
Preflight adjoint (COMMENTED, décision finale réservée à ai-01).
Vérifié sur la tête 735b939ec7a823f5a8fca24990d54f61c2a7a357 :
- la reconstruction demandée sur #14228 est désormais livrée par une PR atomique basée sur
main; diff complet relu : deux fichiers,+122/-6; - body complet, deux commentaires, absence de reviews antérieures et absence de threads inline vérifiés ;
check_unaddressed_nits.py 14242: aucun nit non levé ; check_pr_perimeter.py 14242 --scan-thread:VERDICT: OK;- logique fail-closed cohérente : allowlist fermée à
pull_request,push,schedule,workflow_dispatch; triggers connus dangereux conservés sous leurs codes spécifiques et tout autre trigger rejeté parUNSAFE_TRIGGER; - validation de branche :
Scripts Tests (CPU)vert,parity gatevert, always-on guards et metadata verts, Gitleaks et CodeQL verts.
L’ancien PR gate n’a pas exposé un défaut de la PR : l’étape d’agrégation a attendu environ 28 minutes puis a expiré/été annulée avant que les derniers jobs CodeQL ne terminent ; CodeQL est désormais entièrement vert. Un dispatch exact-head du mécanisme borné pr-gate-rerun.yml a été lancé pour cette tête (run 33608363042), sans nouveau push.
La PR #14228 devient un véhicule supersédé à fermer seulement après décision du coordinateur ; je ne la ferme pas dans ce rôle adjoint. La décision de merge de #14242 reste réservée à ai-01.
jsboige
left a comment
There was a problem hiding this comment.
Complément exact-head au preflight : le dispatch borné pr-gate-rerun.yml run 33608363042 a terminé SUCCESS, puis le check PR gate de la tête 735b939ec7a823f5a8fca24990d54f61c2a7a357 a terminé SUCCESS à 09:02:30Z. État revérifié : CLEAN / MERGEABLE, tous les checks terminaux verts. Le jalon demandé est donc franchi ; décision de merge réservée à ai-01.
Grain: MED/guard — lane myia-po-2024:CoursIA — prev: LIGHT/docs #14235
Tranche 2 CI self-hosted : triggers des jobs routés — deny → allowlist fail-closed
See #14201— ferme la transche 2 du grain (le denylist de triggers de #14148 est fail-OPEN). La partie « router le sweep + mesurer l'acceptance #12728 » ajoutée à l'issue reste ouverte, livrée dans une PR séparée.Ce que la PR change
scripts/ci/check_self_hosted_runner_policy.py: le refus des triggers fork-atteignables passe d'un denylist (énumérationFORK_REACHABLE_TRIGGERS) à une allowlist fail-closed (SAFE_SELF_HOSTED_TRIGGERS = {pull_request, push, schedule, workflow_dispatch}).check_run/check_suiteportentpull_requests[]+ unhead_sha: uncheckout ${{ github.event.check_suite.head_sha }}exécuterait du code de fork sur le runner — précisément le vecteur que feat(ci,#13378): route 11 pure-Python guards to the Linux self-hosted leg (tranche 1) #14148 a fermé pour les triggers de commentaire, et que le denylist laisse passer.UNSAFE_TRIGGER. La péremption par « nouveau trigger GitHub portant un payload de PR » disparaît : la forme default-deny ne se re-périme pas à chaque nouvel événement.pull_requestgardé pare-repo,push,schedule,workflow_dispatch) restent acceptés — mesuré sur la tranche 1 :banner-guard.yml(push,workflow_dispatch),notebook-cell-source-parses.yml(push),hooks-parity.yml(schedule,push).scripts/tests/test_check_self_hosted_runner_policy.py: 3 nouveaux tests (frontière allowlist, contre-contrôle inclus).Validation
python -m pytest scripts/tests/test_check_self_hosted_runner_policy.py→ 48 passed (les 3 nouveaux tests, plus les 45 existants).python scripts/ci/check_self_hosted_runner_policy.py→workflows=131 jobs=159 self_hosted=14→OK -- all self-hosted jobs satisfy isolation policy(exit 0). Aucun fauxUNSAFE_TRIGGERsur les 11 jobs feat(ci,#13378): route 11 pure-Python guards to the Linux self-hosted leg (tranche 1) #14148 ni sur le sweep.Genre / tier
guard(META) — comme CI: une fixture epinglee a une date absolue a casse main a minuit — 8 candidats de la meme classe, et l'organe qui les prouve #14206, un grain de sécurité/CI assigné par le coordinateur ; ne tient PAS le plancher G-VAR-1. À traiter en side-track, pas en plat principal.See #14201et nonCloses: l'issue porte aussi le scope ajouté (routage du sweep + mesure de l'acceptance CI: l'organe qui repare les PR gates perimes est annule 19 fois sur 30 — 2 min d'execution, 2 h de file #12728), qui n'est pas dans cette PR.Périmètre : 2 fichiers
scripts/ci/check_self_hosted_runner_policy.py(+52 / −6)scripts/tests/test_check_self_hosted_runner_policy.py(+76)Preuve d'identité
feature/13378-tranche2-triggers, rebasée surorigin/main(44cb924068), 1 commit735b939ec7.SAFE_SELF_HOSTED_TRIGGERS).