目的
「push は許可できないが信頼できる fork コントリビュータ」の CI を自動実行しつつ、untrusted な外部 fork PR の CI は承認ゲートで止める、という CI ガバナンスを整える。
背景(GitHub の制約)
GitHub は CI 自動実行の免除を repo の Write 権限に不可分に紐づけている。ゆえに「push は与えないが CI は信頼して自動実行したい」という中間ケースを native には表現できない(Write を与えると push も付く/custom role でも CI 免除は base ロール依存で分離不可)。
また現状の fork PR 承認ポリシーは first_time_contributors=初回のみ承認要のため、一度でも貢献した外部者は以降 fork PR の CI が自動実行され、#387 で議論した「untrusted build が pr-number.txt を改竄してコメント偽装」クラスを承認なしに自動発火できてしまう。
設計
1. 承認ポリシーを引き締め
fork-pr-contributor-approval を all_external_contributors に変更(全ての外部 fork PR の CI を Approve and run 待ちに)。これで untrusted 由来の CI は権限層で止まり、#387 の trade-off も権限層で封殺される。
2. 信頼ユーザー限定の自動承認 workflow を追加
- トリガー =
pull_request_target(=base 側の信頼コンテキストで走る。fork コードは実行しない)
- 権限 =
actions: write(+必要な read 系)
- ロジック:
- PR 作者
github.event.pull_request.user.login を信頼リストと照合
- 該当 → その PR の head SHA で
status=action_required(承認待ち)の workflow run を探し、POST /repos/{owner}/{repo}/actions/runs/{run_id}/approve で自動承認
- 非該当 → 承認待ちのまま(maintainer が手動承認)
→ 信頼ユーザー = bot が即承認して CI 自動実行/untrusted = 承認ゲート。push は一切与えない。
3. 信頼リストの持ち方(どちらか)
- (a) base repo のファイル(例
.github/trusted-ci-contributors.yml)— maintainer が PR で編集・追加 token 不要・シンプル
- (b) Org の Team メンバーシップを API 照合 — 管理は Org UI で楽だが照合に org スコープの token が要る
★安全上の鉄則(pull_request_target ゆえ)
効果
参考
目的
「push は許可できないが信頼できる fork コントリビュータ」の CI を自動実行しつつ、untrusted な外部 fork PR の CI は承認ゲートで止める、という CI ガバナンスを整える。
背景(GitHub の制約)
GitHub は CI 自動実行の免除を repo の Write 権限に不可分に紐づけている。ゆえに「push は与えないが CI は信頼して自動実行したい」という中間ケースを native には表現できない(Write を与えると push も付く/custom role でも CI 免除は base ロール依存で分離不可)。
また現状の fork PR 承認ポリシーは
first_time_contributors=初回のみ承認要のため、一度でも貢献した外部者は以降 fork PR の CI が自動実行され、#387 で議論した「untrusted build がpr-number.txtを改竄してコメント偽装」クラスを承認なしに自動発火できてしまう。設計
1. 承認ポリシーを引き締め
fork-pr-contributor-approvalをall_external_contributorsに変更(全ての外部 fork PR の CI をApprove and run待ちに)。これで untrusted 由来の CI は権限層で止まり、#387 の trade-off も権限層で封殺される。2. 信頼ユーザー限定の自動承認 workflow を追加
pull_request_target(=base 側の信頼コンテキストで走る。fork コードは実行しない)actions: write(+必要な read 系)github.event.pull_request.user.loginを信頼リストと照合status=action_required(承認待ち)の workflow run を探し、POST /repos/{owner}/{repo}/actions/runs/{run_id}/approveで自動承認→ 信頼ユーザー = bot が即承認して CI 自動実行/untrusted = 承認ゲート。push は一切与えない。
3. 信頼リストの持ち方(どちらか)
.github/trusted-ci-contributors.yml)— maintainer が PR で編集・追加 token 不要・シンプル★安全上の鉄則(
pull_request_targetゆえ)効果
参考
actions/runs/{run_id}/approveAPI