Repository navigation
feat(secrets,#17437): organe de creation des GitHub Apps de lane par manifeste (Q39) - #17451
Conversation
…manifeste (Q39) Une App = un clic : une page locale porte un formulaire par lane avec son manifeste pre-rempli ; le callback local echange le code temporaire contre la configuration de l'App et depose la cle privee dans .secrets/github-apps/<slug>.pem, sans telechargement manuel. Permissions : une seule constante pour les 6 lanes (po-2023..27, web1), arbitrage user Q39 « donne tous les droits qui fluidifient notre workflow », chaque droit rattache a un usage mesure (workflows w, actions w pour les reruns/cancel/dispatch, administration r pour la protection de branche, alertes r). Ecartes avec motif : checks w (une App peut fabriquer un check-run vert que le gate lit), administration w, secrets. .gitignore versionne : .secrets/ ignore en entier. Jusqu'ici seules quelques entrees nominatives l'etaient ; master.env et les cles d'App ne l'etaient que par le .git/info/exclude local d'ai-01. Controle positif : le test dedie echoue sur le .gitignore de main. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels |
|
VERDICT: LGTM [Hermes] — #17451 (organe GitHub App manifest, Q39, author myia-ai-01). Vérifié firsthand :
Réserve mineure (non bloquante) : le flux dépend d'un geste user (clic « Create GitHub App » + « Install ») — documenté dans le docstring. Reste de la hardcoded CI : |
Path-collision (organ #13359/#13615)Cette PR #17451 (
|
|
[ADJOINT PREFLIGHT] Pourquoi ce dossier n'est pas READY — tête
Le reste est conforme. Hermes a approuvé cette même tête, avec les 16 tests exécutés. Le diff compte 3 fichiers (+474/−0) et correspond au body. Le recouvrement |
…rets_dir CodeQL (py/clear-text-logging-sensitive-data, alerte #143) classait la variable `secrets_dir` comme donnee sensible sur la seule foi de son nom, et le message de refus qui l'imprime comme une fuite : la valeur est le CHEMIN du depot des cles, jamais une cle. Un `# codeql[...]` serait inerte (default setup) ; le nom dit maintenant ce que la variable porte. Le drapeau CLI `--secrets-dir` est conserve (dest="key_dir"). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
[ADJOINT PREFLIGHT] Prévalidation technique, pas décision de merge. Diff complet : |
Grain: MED/tooling — lane myia-ai-01:CoursIA — prev: LIGHT/docs #17450
Résumé
Poste « Création des Apps » de #17437 : une App = un clic. Arbitrage user du 2026-09-22 sur Q39 (vaut sign-off) : « donne tous les droits qui fluidifient notre workflow ».
scripts/secrets/github_app_manifest.pysert une page locale (127.0.0.1) avec un formulaire par lane, chacun portant son manifeste pré-rempli. Après « Create GitHub App », GitHub renvoie uncodetemporaire au callback local, qui l'échange (POST /app-manifests/{code}/conversions, sans authentification, valable 1 h) et dépose la clé privée dans.secrets/github-apps/<slug>.pem. Plus de « Generate a private key » ni de.pemqui traîne dans un dossier de téléchargements. La page de retour donne le lien d'installation avec le compte et le dépôt CoursIA pré-sélectionnés.Permissions — une constante, six lanes, chaque droit rattaché à un usage mesuré
« Tous les droits qui fluidifient » est traduit en usages mesurés (
git grepsurscripts/et.claude/), pas en liste maximale :contents·pull_requests·issuesupdate-branch, PR, reviews, levées, claims, labelsworkflows.github/workflows/**actionsrerun,cancel(scripts/pr_gate.py:1177),gh workflow run pr-gate-stale-sweep.yml, éviction de caches (evict_orphan_caches.py) — le pilote n'avait quereadadministrationactions/runnerssansRUNNERS_READ_PATsecurity_events·vulnerability_alerts·secret_scanning_alertschecks·statuses·metadataÉcartés, avec motif (constante
EXCLUDED, testée) :checks: write— seules les Apps peuvent créer un check-run ; un PAT ne le peut pas. Ce serait donner à chaque lane un moyen, qu'elle n'a pas aujourd'hui, de fabriquer le vert que lit le merge-gate. Aucun usage de lane hors Actions.administration: write— suppression du dépôt, levée de la protection demain.secrets— aucun usage.Le pilote
coursia-lane-ai-01(App 5036190) n'est pas recréé. Mesuré par JWTGET /app: 8 permissions, dontactions: read. Il s'aligne sur la même constante depuis sa page de réglages, et l'installation accepte ensuite les nouvelles permissions..gitignoreversionné :.secrets/en entierJusqu'ici, le
.gitignoreversionné ne listait que des fichiers nominatifs de.secrets/.master.envet les clés d'App n'étaient ignorés que par le.git/info/excludelocal d'ai-01 (git check-ignore -vnomme.git/info/exclude:24comme source). Sur un clone sans cette exclusion locale, une clé d'App aurait pu être commitée..secrets/est désormais ignoré en entier (0 fichier suivi dessous, vérifié pargit ls-files .secrets). L'organe refuse en plus d'écrire une clé sur un chemin quegit check-ignorene couvre pas.Vérifications
python -m pytest scripts/secrets/tests/test_github_app_manifest.py -q: 16 passed..gitignoredemainremis en place (copie de sauvegarde, puis restauration),test_secrets_dir_is_ignored_by_the_versioned_ruleéchoue. Le test attrape donc bien l'absence de la règle.is_git_ignored:Truesur.secrets/github-apps/probe.pem(clone principal et worktree),Falsesurscripts/probe.pem(témoin négatif).--print-manifest web1.statefalsifié → 400 sans conversion, et la clé n'apparaît jamais dans la page renvoyée.Hors de cette PR
jsboige, un clic par App puis un clic « Install ».destruct_after, comme l'autorisesecrets-hygiene.md).SHARED_GITHUB_LOGIN/COORDINATOR_LOGINdanscheck_adjoint_prevalidation.py, à faire avant qu'une lane ne signe sous son App (poste distinct de GitHub Apps par lane : les comptes machine sont bridés au tarif anonyme (60 req/h, GraphQL 0) et hors-limite CGU #17437).See #17437.
🤖 Generated with Claude Code