From 6d6b109d98064993036db6f558a5efec2c11219d Mon Sep 17 00:00:00 2001 From: Don Petry <36422719+don-petry@users.noreply.github.com> Date: Sun, 19 Jul 2026 16:57:33 -0500 Subject: [PATCH] docs: define release-manager App required permissions (incl. Workflows:write) The canary-rollout header listed the App's perms but omitted Workflows:write, which #807 established is REQUIRED to move channel tags on workflow-heavy repos like .github (else 403 'Resource not accessible by integration'). Spell out the full required-permission set + the grant-AND-request rule (create-github-app-token drops any permission the mint step doesn't list). Also fix the stale ADR line that still named GH_PAT_WORKFLOWS as the mover. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/canary-rollout.yml | 27 ++++++++++++++++++---- docs/initiatives/agent-canary-rings-adr.md | 9 ++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.github/workflows/canary-rollout.yml b/.github/workflows/canary-rollout.yml index 20da542d2..49a3d13af 100644 --- a/.github/workflows/canary-rollout.yml +++ b/.github/workflows/canary-rollout.yml @@ -11,11 +11,28 @@ # # Auth: the mover credential is a GitHub App installation token minted at runtime via # actions/create-github-app-token from RELEASE_MANAGER_APP_CLIENT_ID (variable) + RELEASE_MANAGER_APP_KEY (secret) (scoped, -# rotatable, auditable) — NOT a raw PAT and NOT github.token. The App carries -# Contents:write (tag moves on the host repos), Deployments:write, Issues:write (the -# per-agent blocker issues in sync-issues; the fleet-status table goes to the job summary, -# not an issue), Actions:read (the gate reads workflow-run history across every tier repo) -# and Metadata:read. Minting +# rotatable, auditable) — NOT a raw PAT and NOT github.token. +# +# REQUIRED release-manager App repository permissions (set BOTH on the App AND +# requested in the token-mint step — `create-github-app-token` restricts the minted +# token to exactly the `permission-*` it lists, so a grant the step doesn't request +# is silently absent): +# • Contents: write — tag moves / annotated-tag creation on the host repos. +# • Workflows: write — REQUIRED to move a channel tag on a repo whose HEAD touches +# `.github/workflows/**`. GitHub blocks an App without it from +# creating/updating such a tag; via the git-refs API this +# surfaces as 403 "Resource not accessible by integration" +# (NOT a ruleset error). The `.github` repo is all reusable +# workflows, so EVERY promotion there needs it (#807; broke the +# fleet 2026-07-13..07-19 while only Contents:write was granted). +# • Deployments: write — the promotion Deployment record. +# • Issues: write — the per-agent blocker issues in sync-issues (fleet-status +# table goes to the job summary, not an issue). +# • Actions: read — the gate reads workflow-run history across every tier repo. +# • Metadata: read. +# The App must also be a bypass actor on each host repo's `release-channel-tags` +# ruleset (that gate is separate from, and insufficient without, the perms above). +# Minting # is a HARD requirement: if the token cannot be minted the job fails — it must not # silently degrade to github.token, which cannot move protected `.github` tags (#868). # diff --git a/docs/initiatives/agent-canary-rings-adr.md b/docs/initiatives/agent-canary-rings-adr.md index 8e721efd4..d63ae14b8 100644 --- a/docs/initiatives/agent-canary-rings-adr.md +++ b/docs/initiatives/agent-canary-rings-adr.md @@ -44,8 +44,13 @@ known-good version while the candidate soaks, and (d) roll back in one move. ## Consequences - **Zero caller churn; bounded blast radius; <5-min rollback** (one tag move). -- The promotion workflow is the authorized tag mover (via `GH_PAT_WORKFLOWS` today; - a dedicated GitHub App scopes the ruleset bypass later). +- The promotion workflow is the authorized tag mover, authenticated as the + **`petry-projects-release-manager` GitHub App** (a bypass actor on each host repo's + `release-channel-tags` ruleset). Its required repository permissions — + **Contents:write, Workflows:write, Deployments:write, Issues:write, Actions:read, + Metadata:read** — must be granted on the App *and* requested in the token-mint step; + see the header of `.github/workflows/canary-rollout.yml` for the rationale (notably + Workflows:write, without which `.github` tag moves 403 — #807). - New cost: the membership SoT and gate thresholds must be maintained; an unused reusable never auto-promotes (acceptable — its version doesn't matter until used). - `dev-lead` is the pathfinder (shipped `v1.4.0` this way); `pr-review` and other