15 KiB
source_url, ingested, sha256, discovered_from
| source_url | ingested | sha256 | discovered_from | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| https://zenn.dev/como/articles/draft_github-actions-ai-yaml_zenn | 2026-07-02 | 0d8be1eca1bbfe9a61b5159bf9816da9e77243c0d6b6d9e7e0b0eb3e702f7209 |
|
AI生成のGitHub Actions YAMLで見落としがちなセキュリティチェック
はじめに
GitHub Actionsまわりの2026年6月の変更を見たとき、正直なところ、最初から強い危機感があったわけではありません。
pull_request_target、actions/checkout、Actions cache、workflow trigger。どれもGitHub Actionsを使っていれば見かける言葉です。ただ、外部からリポジトリが攻撃されるとか、CI/CDの入口が悪用されるとか聞いても、どこかで「有名なOSSや大きな組織の話だろう」と思っていました。
自分は、誰かのプルリクエストを大量にレビューするというより、GitHub ActionsでCI/CDを組んだり、GitHubフローを回しやすくしたりする文脈でGitHubに触ることが多いです。最近はそこにAIも入ってきていて、「このプロジェクト用にActionsのYAMLを書いて」「push時にテストして、mainにマージされたらビルドして」のような下書きをAIに作ってもらう場面も増えました。
これはかなり便利です。YAMLの細かい構文やインデントを毎回調べずに済みますし、ゼロから書くより速いことも多いです。
ただ、今回の変更を追いかけてみて、自分はGitHub Actionsを少し「動けばOKの自動化」として見すぎていたなと思いました。AIが作ったYAMLが動くかどうかだけではなく、誰が起動できて、どのコードをcheckoutして、どの権限で実行されるのかを見る必要があります。
この記事は、AIにGitHub Actionsを書かせること自体を避けるためのものではありません。むしろ、AIにたたき台を作ってもらう前提で、人間がどこを確認すべきかを整理するためのメモです。
実際、GitHub ActionsのYAMLをAIに作ってもらう場面は増えています。
たとえば、次のような依頼です。
- push時にテストを実行する
- pull request作成時にLintとビルドを回す
- mainへマージされたらデプロイする
- リリースタグ作成時にパッケージを公開する
- Dependabotや外部PRに対して自動コメントを返す
AIは、この種のたたき台をかなり自然に作れます。構文やインデントを調べる手間も減ります。
ただし、GitHub ActionsのYAMLは単なる設定ファイルではありません。実行権限、シークレット、キャッシュ、アーティファクト、リリース、デプロイに関わるため、書き方を間違えるとリポジトリ全体のセキュリティに影響します。
この記事では、2026年6月のGitHub Actions関連アップデートを踏まえ、AIが生成したActions YAMLを見る時に確認したいポイントを整理します。
背景: 2026年6月のGitHub Actions関連変更
GitHubは2026年6月に、Actionsの信頼境界に関する変更を複数発表しています。
pull_request_targetとactions/checkoutの組み合わせをより安全な既定値へ寄せる変更- untrusted triggersからのActions cacheを読み取り専用にする変更
- 誰が、何をきっかけにworkflowを起動できるかを制御する方向のアップデート
これらは個別には小さな変更に見えますが、共通しているのは「外から来た入力を、どの権限で実行してよいか」という問題です。
GitHub Actionsでは、イベント、checkout対象、トークン権限、シークレット、キャッシュ、アーティファクトが組み合わさって動きます。AIが生成したYAMLを見る時も、「動くかどうか」だけでなく、この信頼境界を確認する必要があります。
チェック1: pull_request_target を使っていないか
まず見るべきなのは、トリガーです。
on:
pull_request_target:
pull_request_target は、pull requestに反応して動くイベントですが、ベースリポジトリ側の文脈で実行されます。通常の pull_request より強い権限を扱えるため、ラベル付け、コメント、権限が必要な処理などには便利です。
ただし、外部PR側のコードをcheckoutして実行する用途には注意が必要です。
危険になりやすい形は、次のような組み合わせです。
on:
pull_request_target:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
- run: npm test
この例では、pull_request_target の強い文脈で、PR側のコードをcheckoutして実行しています。外部から来たPRに悪意あるコードが含まれていた場合、そのコードを強い権限の環境で動かすことになります。
確認観点は次です。
- 本当に
pull_request_targetが必要か - 通常の
pull_requestで足りないか pull_request_target内でPR側のコードをcheckoutしていないか- checkoutしたコードを
npm test、python script.py、bash script.shなどで実行していないか - 権限が必要な処理と、PR側コードを実行する処理を分離できないか
GitHub Security Labの「Preventing pwn requests」は、この問題を理解するために読んでおく価値があります。
チェック2: permissions が最小限になっているか
AIが生成したYAMLでは、permissions が省略されることがあります。
省略時の挙動はリポジトリや組織の設定に依存するため、workflow側で明示しておく方が読みやすく、安全側に寄せやすくなります。
テストやLintだけなら、まずは読み取り専用を基本にします。
permissions:
contents: read
pull requestへコメントを書く場合は、必要な権限を明示します。
permissions:
contents: read
pull-requests: write
パッケージ公開やリリース作成が必要なworkflowでは、contents: write や packages: write が必要になることがあります。ただし、必要なjobだけに閉じることを検討します。
確認観点は次です。
permissionsが明示されているか- テストだけのworkflowに書き込み権限が付いていないか
- job単位で権限を絞れるか
- デプロイやリリース用の権限が、PR由来のworkflowで使われていないか
id-token: writeを使う場合、OIDCの条件が適切か
AIが「動かすため」に強めの権限を出してきた場合、人間が引き算する必要があります。
チェック3: checkoutしているコードがどこ由来か
Actionsでは、何をcheckoutしているかが重要です。
特にPRイベントでは、次の違いを意識します。
- ベースリポジトリ側のコード
- PRのマージ結果
- PR head側のコード
- fork元から来たコード
AIが生成したYAMLでは、ref: に github.event.pull_request.head.sha や github.head_ref を使うことがあります。
それ自体が常に悪いわけではありません。ただし、どの権限でそのコードを実行するかとセットで見ます。
確認観点は次です。
actions/checkoutのrefが何を指しているか- fork元PRのコードをcheckoutしていないか
- checkoutしたコードを強い権限で実行していないか
- 権限が必要な処理の前に、外部由来コードを実行していないか
pull_request_target とPR headのcheckoutが組み合わさっている場合は、特に慎重に見ます。
チェック4: cacheとartifactを書き込ませてよいか
Actions cacheはビルド高速化に便利です。
ただし、キャッシュは次回以降の実行に影響します。信頼できないトリガーからキャッシュを書き込めると、後続の信頼されたworkflowが汚染されたキャッシュを読む可能性があります。
GitHubは2026年6月、untrusted triggersからのActions cacheを読み取り専用にする変更を発表しました。これは、キャッシュも信頼境界の一部として扱う流れです。
確認観点は次です。
- 外部PRや自動生成PRからcacheを書き込ませていないか
- cache keyにPR由来の値を使っている場合、意図した分離になっているか
- artifactを後続jobや別workflowで信用しすぎていないか
- デプロイ用workflowが、信頼できない入力由来のcacheやartifactを使っていないか
キャッシュやアーティファクトは、単なる高速化や中間ファイルではありません。次の実行へ渡るものとして扱います。
チェック5: サードパーティActionを丸呑みしていないか
AIは便利なサードパーティActionを提案することがあります。
steps:
- uses: some-user/some-action@v1
この時、少なくとも次を確認します。
- そのActionは実在するか
- 作者や組織は信頼できるか
- README、更新履歴、Issueの状態は妥当か
- 公式Actionで代替できないか
- タグ固定でよいか、コミットSHA固定が必要か
GitHubのセキュリティガイドでは、サードパーティActionの扱いや、信頼できるActionを使うことの重要性が説明されています。
すべてのActionを毎回SHA固定するかは、チームの運用やリスク次第です。ただし、少なくともAIが出してきた uses: を確認せずに通すのは避けた方がよいです。
チェック6: workflowを誰が起動できるか
GitHub Actionsでは、workflowがどのイベントで起動するかも重要です。
on:
pull_request:
workflow_dispatch:
push:
branches:
- main
見るべきなのは、イベントの種類だけではありません。
- forkからのPRで動くのか
- 初回コントリビューターのPRで自動実行されるのか
workflow_dispatchを誰が実行できるのかpush対象ブランチは適切に絞られているか- デプロイworkflowがPRイベントから起動しないか
特にデプロイ、リリース、パッケージ公開、クラウド操作を含むworkflowでは、起動条件を狭くします。
on:
push:
tags:
- "v*.*.*"
あるいは、環境保護ルールや手動承認を組み合わせることも検討します。
AI生成YAMLを見るための短いチェックリスト
AIがGitHub Actions YAMLを生成したら、まず次を見ます。
pull_request_targetを使っているか- PR側のコードをcheckoutして実行していないか
permissionsが明示され、最小限になっているかGITHUB_TOKENやsecretsがPR由来の処理に渡っていないか- cacheやartifactを信頼できない実行元から書き込ませていないか
uses:のActionが信頼できるものか- デプロイやリリースがPRイベントから起動しないか
workflow_dispatchやbranch/tag条件が広すぎないか
このチェックは、AIを使わないためのものではありません。
AIにたたき台を書いてもらい、人間が信頼境界を見るためのものです。
まとめ
GitHub ActionsのYAMLは、見た目は小さな設定ファイルです。
しかし実際には、コードをcheckoutし、シェルを実行し、シークレットやトークンに触れ、リリースやデプロイにつながる実行環境です。
AIはそのYAMLを短時間で作れます。これは便利です。
ただし、AIが生成したYAMLを確認する時は、「動くかどうか」だけではなく、次を見ます。
- 誰が起動するのか
- 何をcheckoutするのか
- どの権限で動くのか
- 何を書き込めるのか
- その結果がどこへ渡るのか
GitHub Actionsの2026年6月の変更は、CI/CDの入口を安全側に寄せる流れとして読めます。
AIにYAMLを作ってもらう時代だからこそ、人間はYAMLの構文よりも、信頼境界を見る力を持っておきたいところです。
参考
- GitHub Changelog: Safer pull_request_target defaults for GitHub Actions checkout https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/ (https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/)
- GitHub Changelog: Read-only Actions cache for untrusted triggers https://github.blog/changelog/2026-06-26-read-only-actions-cache-for-untrusted-triggers/ (https://github.blog/changelog/2026-06-26-read-only-actions-cache-for-untrusted-triggers/)
- GitHub Changelog: Control who and what triggers GitHub Actions workflows https://github.blog/changelog/2026-06-18-control-who-and-what-triggers-github-actions-workflows/ (https://github.blog/changelog/2026-06-18-control-who-and-what-triggers-github-actions-workflows/)
- GitHub Security Lab: Preventing pwn requests https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/ (https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/)
- GitHub Docs: Security hardening for GitHub Actions
https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions (https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions)
tikomo (/como) AIがシステム開発する時代、「人間の開発日誌って意味があるの?」と悩み中... 確かに「作る」は速くなったけど「理解する」のは...やっぱり時間がかかります。 「本当に理解するって必要なの」とに問いかけながら「ヤル」そういうものと信じるw AIとはバランスをもって付き合いたいw バッジを贈って著者を応援しよう バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。