Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions .github/workflows/gate-attestation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ jobs:
steps:
# WHY: waiver keys off the PR author login, not github.actor — actor flips
# to a maintainer login on "Re-run failed jobs", re-arming the check on bot PRs.
# Release-please is ALSO waived branch-shaped: under GITHUB_TOKEN its PRs
# are authored as github-actions[bot] (and as the PAT owner once a PAT is
# wired) — the author varies, the branch pattern does not. Release-PR
# content is generated version bumps; its verification is the live
# deny/audit/osv checks.
#
# WARNING: the release-please branch pattern is paired with a Bot author
# type and is NEVER sufficient alone. `github.head_ref` is chosen by
# whoever opens the PR, so a branch-shaped waiver is a predicate the
# checked party controls: a branch named `release-please--branches--x`
# would otherwise skip the Gate-Passed trailer verification entirely on
# any content. The env-var indirection below already treats head_ref as
# attacker-controlled for shell-injection purposes — the same property
# disqualifies it as a trust predicate. The pattern stays because
# release-please's LOGIN varies (github-actions[bot] under GITHUB_TOKEN,
# a PAT owner after kanon#1092) while its branch shape does not;
# `user.type` is the half a pusher cannot forge.
- name: Pass trusted automation PRs
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'release-please[bot]' || startsWith(github.head_ref, 'release-please--branches--') }}
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'release-please[bot]' || (startsWith(github.head_ref, 'release-please--branches--') && github.event.pull_request.user.type == 'Bot') }}
env:
# WHY: head_ref is attacker-controlled text — env-var indirection keeps
# it out of shell interpolation (actionlint expression rule).
Expand All @@ -43,14 +50,14 @@ jobs:
# same status GitHub uses for a superseded run, so a slow clone is
# indistinguishable from a supersede and presents as a gate failure.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'release-please[bot]' && !startsWith(github.head_ref, 'release-please--branches--') }}
if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'release-please[bot]' && !(startsWith(github.head_ref, 'release-please--branches--') && github.event.pull_request.user.type == 'Bot') }}
with:
fetch-depth: 0
filter: blob:none
persist-credentials: false

- name: Verify Gate-Passed trailer
if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'release-please[bot]' && !startsWith(github.head_ref, 'release-please--branches--') }}
if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' && github.event.pull_request.user.login != 'release-please[bot]' && !(startsWith(github.head_ref, 'release-please--branches--') && github.event.pull_request.user.type == 'Bot') }}
# WHY (#2399): bind to the PR TIP, not "any PR commit". The old loop
# passed if any ancestor carried a Gate-Passed trailer, so an un-stamped
# tip could ride an earlier commit's attestation — a false green on the
Expand Down
35 changes: 26 additions & 9 deletions .github/workflows/hybrid-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -446,15 +446,29 @@ jobs:

- name: Verify no AI attribution
# WHY: lifted verbatim from kanon's own gate-attestation.yml (and
# harmonia's inline copy) — one implementation, centralized. Waivers
# match check-trailer's: PR-author-shaped for dependabot, branch-shaped
# for release-please (its author varies: github-actions[bot] under
# GITHUB_TOKEN today, a future PAT owner post kanon#1092 — the branch
# pattern is what stays stable). Runs regardless of docs_only_exemption
# — a docs-only PR still carries its own title/body/commits and must
# not smuggle an attribution marker through the build exemption.
# harmonia's inline copy) — one implementation, centralized. Runs
# regardless of docs_only_exemption — a docs-only PR still carries its
# own title/body/commits and must not smuggle an attribution marker
# through the build exemption.
#
# WARNING: the release-please waiver requires BOTH the branch shape and
# a Bot author type, and neither alone is sufficient. `github.head_ref`
# is the branch name chosen by whoever opens the PR, so a branch-shaped
# waiver is a predicate the checked party controls — anyone could name a
# branch `release-please--branches--x` and exempt any content. The
# branch pattern still has to be part of it, because release-please's
# LOGIN varies (github-actions[bot] under GITHUB_TOKEN today, a PAT
# owner after kanon#1092) while its branch shape does not. `user.type`
# supplies the half the branch cannot: GitHub derives it from the
# resolved account and a pusher cannot set it.
#
# NOTE: when kanon#1092 moves release-please to a PAT-owned (human)
# account, `user.type` becomes "User" and this waiver stops firing — the
# release PR goes red rather than silently exempt, which is the correct
# direction to fail. Add that login to an explicit allowlist then.
env:
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
PR_AUTHOR_TYPE: ${{ github.event.pull_request.user.type }}
PR_BODY: ${{ github.event.pull_request.body }}
PR_HEAD_REF: ${{ github.head_ref }}
PR_TITLE: ${{ github.event.pull_request.title }}
Expand All @@ -463,8 +477,11 @@ jobs:
run: |
case "$PR_HEAD_REF" in
release-please--branches--*)
echo "Release-please branch ($PR_HEAD_REF): AI attribution check exempt."
exit 0
if [ "$PR_AUTHOR_TYPE" = "Bot" ]; then
echo "Release-please branch from bot author ($PR_AUTHOR): AI attribution check exempt."
exit 0
fi
echo "Branch $PR_HEAD_REF has the release-please shape but author $PR_AUTHOR is type ${PR_AUTHOR_TYPE:-unknown}, not Bot — not waiving."
;;
esac
if [ "$PR_AUTHOR" = "dependabot[bot]" ]; then
Expand Down