securing-github-actions-workflows について
GitHub Actionsを利用するチーム向けに、トークン権限、Actionのバージョン固定、信頼できない入力、デプロイ用シークレットの保護を扱うワークフロー強化スキルです。サプライチェーン攻撃やワークフローへのコード注入リスクを抑えます。
主な機能
- 01ActionをSHAダイジェストに固定
- 02GITHUB_TOKENの権限を制限
- 03信頼できない入力によるスクリプト注入を防止
- 04Forkからのプルリクエストを安全に処理
- 05シークレットを保護し環境承認を設定
- 06CODEOWNERSでワークフロー変更を管理
活用シーン
- 01サードパーティAction侵害のリスク低減
- 02本番デプロイ用ワークフローの強化
- 03プルリクエスト内容によるコマンド注入の防止
- 04ワークフローファイル変更のレビュー必須化
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill securing-github-actions-workflowsインストール後、Claude Code で/securing-github-actions-workflowsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
GitHub Actions ワークフローのセキュリティ強化
使用する場面
- GitHub Actions を CI/CD プラットフォームとして使用しており、サプライチェーン攻撃に対するワークフローの強化が必要な場合
- ワークフローでシークレットを扱う場合、本番環境にデプロイする場合、または高い権限を持つ場合
- 信頼できない PR タイトル、ブランチ名、コミットメッセージを介したスクリプトインジェクションを防ぐ場合
- ワークフローの変更に対して監査証跡と承認ゲートが必要な場合
- サードパーティ製アクションの変更可能なバージョンタグがサプライチェーンリスクとなる場合
使用しないでください。他の CI/CD プラットフォームのセキュリティ強化(プラットフォーム固有のセキュリティ強化ガイドを参照)、アプリケーションの脆弱性スキャン(SAST/DAST を使用)、またはコード内のシークレット検出(Gitleaks を使用)には適していません。
前提条件
- GitHub Actions が有効な GitHub リポジトリ
- 組織レベルの設定を行うための GitHub 組織管理者アクセス権
- GitHub Actions のワークフロー構文とイベントに関する理解
ワークフロー
ステップ 1:アクションを SHA ダイジェストに固定する
# INSECURE: Mutable tag can be overwritten by attacker
- uses: actions/checkout@v4
# SECURE: Pinned to immutable SHA digest
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Use Dependabot to auto-update pinned SHAs
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
ステップ 2:GITHUB_TOKEN の権限を最小限にする
# Set restrictive default permissions at workflow level
name: CI Pipeline
permissions: {} # Start with no permissions
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read # Only what's needed
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
permissions:
contents: read
deployments: write
id-token: write # For OIDC-based cloud auth
steps:
- name: Deploy
run: echo "deploying"
ステップ 3:スクリプトインジェクションを防ぐ
# VULNERABLE: User-controlled input in run step
- run: echo "PR title is ${{ github.event.pull_request.title }}"
# SECURE: Use environment variable (properly escaped by shell)
- name: Process PR
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BODY: ${{ github.event.pull_request.body }}
run: |
echo "PR title is ${PR_TITLE}"
echo "PR body is ${PR_BODY}"
# SECURE: Use actions/github-script for complex operations
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
with:
script: |
const title = context.payload.pull_request.title;
console.log(`PR title: ${title}`);
ステップ 4:フォークからのプルリクエストを安全に扱う
# DANGEROUS: pull_request_target runs with base repo permissions
# on: pull_request_target # AVOID unless absolutely necessary
# SAFE: pull_request runs in fork context with limited permissions
on:
pull_request:
branches: [main]
# If pull_request_target is required, never checkout PR code:
on:
pull_request_target:
types: [labeled]
jobs:
safe-job:
if: contains(github.event.pull_request.labels.*.name, 'safe-to-test')
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# NEVER do: actions/checkout with ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
# This checks out the BASE branch, not the PR
ステップ 5:シークレットと環境変数を保護する
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Requires approval
steps:
- name: Deploy with secret
env:
# Secrets are masked in logs automatically
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
# Never echo secrets
# echo "$DEPLOY_KEY" # BAD
deploy-tool --key-file <(echo "$DEPLOY_KEY")
- name: Audit secret access
run: |
# Log that secret was used without exposing it
echo "::notice::Deploy key accessed for production deployment"
ステップ 6:ワークフロー変更の管理策を導入する
# Require CODEOWNERS approval for workflow changes
# .github/CODEOWNERS
.github/workflows/ @security-team @platform-team
.github/actions/ @security-team @platform-team
# Organization settings:
# 1. Settings > Actions > General > Fork PR policies
# - Require approval for first-time contributors
# - Require approval for all outside collaborators
# 2. Settings > Actions > General > Workflow permissions
# - Read repository contents and packages permissions
# - Do NOT allow GitHub Actions to create and approve PRs
主な概念
| 用語 | 定義 |
|---|---|
| SHA 固定 | 変更可能なバージョンタグではなく、変更不可能なコミット SHA を使って GitHub Actions を指定すること |
| スクリプトインジェクション | 信頼できない入力(PR タイトル、ブランチ名など)がシェルコマンドに埋め込まれる攻撃 |
| GITHUB_TOKEN | 現在のリポジトリにスコープを限定し、権限を設定できる、自動生成のトークン |
| pull_request_target | フォークからの PR に対し、ベースリポジトリのコンテキストで完全な権限を持って実行される危険なイベントトリガー |
| 環境保護 | 環境にアクセスするジョブの実行前に手動承認を必須にする GitHub の機能 |
| CODEOWNERS | ワークフローファイルを含む特定のパスに対して、必要なレビュアーを定義するファイル |
| OIDC フェデレーション | 長期有効な認証情報を保存せずに、GitHub の OIDC トークンを使ってクラウドプロバイダーに認証すること |
ツールとシステム
- Dependabot:固定したアクションの SHA を最新の状態に保つ、自動依存関係更新ツール
- StepSecurity Harden Runner:ワークフローからの送信ネットワーク通信を監視し、制限する GitHub Action
- actionlint:GitHub Actions のワークフローファイルを対象とするリンター。セキュリティ上の問題を検出します
- allstar:リポジトリにセキュリティポリシーを適用する OpenSSF の GitHub アプリ
- scorecard:CI/CD を含むサプライチェーンのセキュリティ対策を評価する OpenSSF のツール
よくあるシナリオ
シナリオ:侵害されたサードパーティ製アクションを介したサプライチェーン攻撃の防止
状況:広く使われている GitHub Action が侵害され、認証情報を盗むコードを含むように v3 タグが更新されます。@v3 を使っているリポジトリは、悪意のあるバージョンを自動的に取得します。
対応方法:
- すべてのリポジトリで、直ちにすべてのアクションを SHA ダイジェストに固定する
- SHA の更新を管理できるよう、github-actions エコシステム向けに Dependabot を設定する
- GITHUB_TOKEN の権限を制限し、アクションが侵害された場合でもアクセスを最小限に抑える
- StepSecurity harden-runner を追加し、異常な送信ネットワーク通信を検出する
- すべてのサードパーティ製アクションを確認し、不要なものをインラインスクリプトに置き換える
- .github/workflows/ への変更に CODEOWNERS の承認を必須にする
注意点:Dependabot を使わずに SHA を固定すると、アクションに対する正当なセキュリティ更新を見逃します。権限を過度に制限すると、正当なワークフローが機能しなくなる場合があります。ラベルによるゲート制御に pull_request_target を使う場合も、ワークフローが PR のコードをチェックアウトするとシークレットが露出します。
出力形式
GitHub Actions Security Audit
================================
Repository: org/web-application
Date: 2026-02-23
WORKFLOW ANALYSIS:
Total workflows: 8
Total action references: 34
SHA PINNING:
[FAIL] 12/34 actions use mutable tags instead of SHA digests
- .github/workflows/ci.yml: actions/setup-node@v4
- .github/workflows/deploy.yml: aws-actions/configure-aws-credentials@v4
PERMISSIONS:
[FAIL] 3/8 workflows have no explicit permissions (inherit default)
[WARN] 1/8 workflows request write-all permissions
SCRIPT INJECTION:
[FAIL] 2 workflow steps interpolate user input directly
- .github/workflows/pr-check.yml:23: ${{ github.event.pull_request.title }}
SECRETS:
[PASS] No secrets exposed in workflow logs
[PASS] All production deployments use environment protection
SCORE: 6/10 (Remediate 5 HIGH findings)
コメント
Markdown 対応