資料 - セキュリティ、制限とインポート機能
GitHub Actionsは、CI/CDパイプラインを構築する上で非常に強力なツールです。しかし、その柔軟性の高さゆえに、セキュリティリスクやスケール時の制約を理解せずに使うと、思わぬ問題に直面することがあります。
本記事では、GitHub Actionsの公式ドキュメントをもとに、セキュアなワークフロー設計からスケール時の制限事項、そして既存CI/CDからの移行まで、実務で必要となる知識を体系的に解説します。
目次
- ワークフローセキュリティの基本原則
- シークレット管理のベストプラクティス
- スクリプトインジェクション攻撃への対策
- サードパーティアクションの安全な利用
- OIDC による認証の近代化
- ランナーのセキュリティ強化
- スケール時の制限事項
- 既存CI/CDからの移行戦略
- セキュリティ機能の総合活用
1. ワークフローセキュリティの基本原則
GitHub Actionsのセキュリティは、「最小権限の原則」を中心に設計されています。ワークフローに必要以上の権限を与えないことが、セキュリティインシデントを防ぐ第一歩です。
GITHUB_TOKENの権限制御
GITHUB_TOKENは、ワークフロー内でGitHub APIにアクセスするための自動生成トークンです。デフォルトでは読み取り専用権限を設定し、必要な場合のみジョブ単位で権限を昇格させます。
# ワークフロー全体でデフォルト権限を読み取り専用に設定
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
# このジョブのみ書き込み権限を付与
permissions:
contents: write
packages: write
steps:
- uses: actions/checkout@v4
- name: "デプロイ処理"
run: |
echo "デプロイを実行"
この設定により、万が一ワークフローの一部が侵害された場合でも、被害範囲を最小限に抑えることができます。
2. シークレット管理のベストプラクティス
シークレットの取り扱いは、CI/CDセキュリティの核心です。GitHubは自動的にログからシークレットを編集しますが、完全ではありません。
シークレット使用時の基本ルール
構造化データの問題
以下のような使い方は避けてください:
# ❌ 悪い例:JSON全体をシークレットに保存
secrets:
API_CONFIG: '{"key": "secret123", "endpoint": "https://api.example.com"}'
# ✅ 良い例:個別にシークレットを分割
secrets:
API_KEY: 'secret123'
API_ENDPOINT: 'https://api.example.com'
構造化データをシークレットにすると、ログからの自動編集が正しく機能しない可能性が高まります。
派生値の登録
シークレットを使って別の機密情報を生成する場合、その生成値も必ずシークレット登録します:
- name: "JWT生成"
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
run: |
# 秘密鍵からJWTを生成
JWT=$(generate_jwt "$PRIVATE_KEY")
# 生成したJWTをマスク(シークレットとして登録)
echo "::add-mask::$JWT"
echo "JWT=$JWT" >> $GITHUB_OUTPUT
::add-mask::コマンドを使うことで、生成された値がログに出力されても自動的に編集されます。
シークレットの命名規則
シークレット名には以下の制約があります:
- 英数字(
[a-z],[A-Z],[0-9])とアンダースコア(_)のみ使用可能 -
GITHUB_プレフィックスで始めることは不可 - 数字で始めることは不可
- 大文字小文字を区別しない(GitHubは大文字で保存)
- 作成場所(リポジトリ、組織、エンタープライズ)内で一意である必要がある
シークレットの制限
- 組織レベル:最大1,000個
- リポジトリレベル:最大100個
- 環境レベル:最大100個
- サイズ制限:48KB
より大きなシークレットが必要な場合は、クラウドストレージやシークレット管理サービス(AWS Secrets Manager、Azure Key Vault等)の利用を検討してください。
シークレットが読み込まれるタイミング
- 組織およびリポジトリのシークレット:ワークフロー実行がキューに入れられたとき
- 環境のシークレット:環境を参照するジョブが開始されたとき
この仕様を理解しておくことで、シークレットの更新タイミングを適切に計画できます。
シークレットの自動編集対象
GitHubは以下の機密情報を自動的にログから編集します:
- 32バイトおよび64バイトのAzureキー
- Azure AD クライアントアプリのパスワード
- Azure Cacheキー
- Azure Container Registryキー
- Azure Function hostキー
- Azure Searchキー
- データベース接続文字列
- HTTP Bearerトークンヘッダー
- JWT
- NPM authorトークン
- NuGet APIキー
- v1 GitHubインストールトークン
- v2 GitHubインストールトークン(
ghp,gho,ghu,ghs,ghr) - v2 GitHub PAT
この自動編集機能があるものの、構造化データや予期しない形式での使用は編集が機能しない可能性があるため、基本原則を守ることが重要です。
3. スクリプトインジェクション攻撃への対策
GitHub Actionsで最も注意すべき脆弱性の一つが、スクリプトインジェクション攻撃です。特にプルリクエストのタイトルやコミットメッセージなど、外部からの入力を直接シェルスクリプトに埋め込むと危険です。
攻撃シナリオ
# ❌ 危険な例
- name: "PRタイトルをチェック"
run: |
if [[ "${{ github.event.pull_request.title }}" =~ ^octocat ]]; then
echo "タイトルはoctocatで始まります"
fi
攻撃者が以下のようなPRタイトルを設定すると:
"; rm -rf $GITHUB_WORKSPACE; echo "
実際に実行されるコマンドは:
if [[ ""; rm -rf $GITHUB_WORKSPACE; echo "" =~ ^octocat ]]; then
ワークスペース全体が削除される可能性があります。
対策1: 環境変数経由での受け渡し(推奨)
# ✅ 安全な例
- name: "PRタイトルをチェック"
env:
TITLE: ${{ github.event.pull_request.title }}
run: |
if [[ "$TITLE" =~ ^octocat ]]; then
echo "タイトルはoctocatで始まります"
else
echo "タイトルはoctocatで始まりません"
fi
この方法では、GitHubコンテキストの値がメモリ上の環境変数として扱われ、スクリプト生成プロセスと相互作用しません。
対策2: カスタムアクションの利用
# ✅ より安全:専用アクションを使用
- uses: example-org/check-pr-title@v3
with:
title: ${{ github.event.pull_request.title }}
JavaScriptアクションを作成すると、コンテキスト値が引数として渡されるため、インジェクション攻撃のリスクが根本的に排除されます。
4. サードパーティアクションの安全な利用
ワークフロー内のジョブは相互に影響を及ぼす可能性があります。一つのアクションが侵害されると、リポジトリに設定されたすべてのシークレットやGITHUB_TOKENにアクセスされる可能性があります。
アクションのピン留め戦略
完全なコミットSHAでのピン留め(推奨)
# ✅ 最も安全:完全なコミットSHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
コミットSHAは不変であり、悪意のある変更からワークフローを保護します。ただし、SHA-1の衝突攻撃のリスクは理論上存在します。
タグでのピン留め(条件付き推奨)
# ⚠️ 作者を信頼できる場合のみ
- uses: actions/checkout@v4
GitHubマーケットプレイスの「Verified creator」バッジは有用な判断材料です。ただし、タグは移動・削除可能なため、悪意のある者がリポジトリアクセス権を取得すると危険です。
リポジトリ・組織レベルのポリシー設定
GitHub Enterprise Cloudでは、組織またはリポジトリレベルで、アクションを完全なコミットSHAにピン留めすることを強制できます。
5. OIDC による認証の近代化
OpenID Connect(OIDC)は、クラウドプロバイダーへの認証方法を根本的に変えます。長期的な認証情報をシークレットとして保存する代わりに、短命で範囲が限定されたトークンを動的に取得します。
OIDCの仕組み
OIDCトークンの主要なクレーム
| クレーム | 説明 | 用途 |
|---|---|---|
aud |
オーディエンス(対象者) | デフォルトはリポジトリ所有者のURL |
iss |
発行者 | https://token.actions.githubusercontent.com |
sub |
サブジェクト(主体) | トラスト条件の定義に使用 |
repository |
リポジトリ名 | 組織名/リポジトリ名 |
environment |
環境名 | 環境を使用する場合 |
ref |
Git参照 | ブランチやタグ |
job_workflow_ref |
再利用可能ワークフローの参照 | 再利用ワークフロー使用時 |
実装例:AWSへのOIDC認証
name: "AWSデプロイ"
on:
push:
branches: [main]
permissions:
id-token: write # OIDCトークン取得に必須
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: "AWS認証"
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- name: "S3にデプロイ"
run: |
aws s3 sync ./dist s3://my-bucket/
サブジェクトクレームのカスタマイズ
より詳細なアクセス制御のために、サブジェクトクレームをカスタマイズできます。
例1: 特定の環境のみ許可
{
"include_claim_keys": [
"repo",
"context"
]
}
クラウドプロバイダー側の設定:
"sub": "repo:組織名/リポジトリ名:environment:Production"
例2: 再利用可能ワークフローの強制
{
"include_claim_keys": [
"job_workflow_ref"
]
}
クラウドプロバイダー側の設定:
"sub": "job_workflow_ref:組織名/自動化リポジトリ/.github/workflows/oidc.yml@refs/heads/main"
これにより、承認された再利用可能ワークフローからのみクラウドリソースにアクセスできるようになります。
例3: リポジトリの可視性による制限
{
"include_claim_keys": [
"repository_owner",
"repository_visibility"
]
}
クラウドプロバイダー側の設定:
"sub": "repository_owner:組織名:repository_visibility:private"
プライベートリポジトリからのアクセスのみを許可します。
OIDCの設定手順
- REST APIでカスタマイズテンプレートを適用(組織管理者)
- クラウドプロバイダーでトラスト条件を設定
- ワークフローで
id-token: write権限を付与 - 専用アクションを使ってOIDC認証を実行
OIDCトークンを要求するための権限設定
ワークフローまたはジョブでOIDCトークンを取得するには、id-token: write権限が必要です:
# ワークフロー全体で設定
permissions:
id-token: write # OIDCトークン取得に必須
contents: read # actions/checkoutに必要
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
または、特定のジョブのみで設定:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # このジョブのみOIDCトークン取得可能
contents: read
steps:
- uses: actions/checkout@v4
再利用可能ワークフローでのOIDC
- 同じユーザー、組織、エンタープライズ所有の再利用可能ワークフロー:呼び出し元のコンテキストからOIDCトークンにアクセス可能
- 外部の再利用可能ワークフロー:呼び出し元のワークフローまたはジョブレベルで明示的に
id-token: writeを設定する必要があります
OIDCトークンを要求する方法
カスタムアクションは、以下の方法でOIDCトークンを要求できます:
- GitHub Actions Toolkitの使用(推奨)
const core = require('@actions/core');
const token = await core.getIDToken('api://AzureADTokenExchange');
- 環境変数の使用
ランナー上で以下の環境変数が利用可能です:
-
ACTIONS_ID_TOKEN_REQUEST_URL:GitHubのOIDCプロバイダーのURL -
ACTIONS_ID_TOKEN_REQUEST_TOKEN:OIDCプロバイダーへのリクエスト用Bearerトークン
curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange"
OIDCクレームのデバッグ
github/actions-oidc-debuggerアクションを使用すると、実際に送信されるクレームを可視化できます。クラウドプロバイダーと統合する前に、トークンの内容を確認するのに便利です。
6. ランナーのセキュリティ強化
GitHub-hostedランナー
GitHub-hostedランナーは、エフェメラルで隔離された仮想マシン上でコードを実行します。各ジョブ実行後、環境はクリーンアップされます。
SBOM(Software Bill of Materials)の提供
GitHub-hostedランナーには、事前インストールされたソフトウェアのSBOMが提供されています。各リリースの添付ファイルから、sbom.イメージ名.json.zip形式のファイルをダウンロードできます。これを脆弱性スキャナーで検証することで、セキュリティリスクを事前に把握できます。
悪意あるホストへのアクセス拒否
GitHub-hostedランナーの/etc/hostsファイルには、暗号通貨マイニングプールや悪意あるサイトへのアクセスをブロックする設定が含まれています。これらのホストはlocalhostにリダイレクトされます。
Self-hostedランナーのリスク
Self-hostedランナーは、エフェメラルでクリーンな仮想マシンで実行される保証がありません。永続的な侵害のリスクがあります。
Self-hostedランナーを安全に使うには
- パブリックリポジトリでは原則使用しない
-
プライベート/インターナルリポジトリでも慎重に
- フォーク可能なリポジトリ(読み取り権限保持者)は環境とレビューで保護
-
ランナーグループで境界を作る
- 組織・エンタープライズレベルでグループ化
- アクセス制御で影響範囲を限定
-
機密情報を最小限に
- ランナーマシン上の秘密鍵、APIトークンを最小化
- センシティブなサービスへのネットワークアクセスを制限
-
Just-In-Time(JIT)ランナーの利用
- REST APIでエフェメラルなランナーを作成
- 1ジョブ実行後に自動削除
JITランナーの設定例
# REST APIから設定ファイルを取得
# (実際のAPIレスポンスをここに保存)
# ランナー起動時に設定を渡す
./run.sh --jitconfig ${encoded_jit_config}
注意:ハードウェアを再利用する場合、環境情報が漏洩するリスクがあります。自動化でクリーンな環境を保証してください。
ランナーの管理戦略
- 集中管理: 専任チームがいる場合、組織/エンタープライズレベルでランナーを追加
- 分散管理: 各チームが管理する場合、所有権レベル(通常は組織)で追加
リポジトリレベルでのランナー追加は、管理オーバーヘッドが大きく、ランナー数も増えるため推奨されません。
7. スケール時の制限事項
GitHub Actionsをスケールアップする際には、様々な制限に注意が必要です。
ワークフロー実行の制限
| 制限カテゴリ | 制限値 | 説明 |
|---|---|---|
| ワークフロー実行時間 | 35日 | この期間を超えるとキャンセル |
| ゲート承認待機時間 | 30日 | 環境承認の最大待機時間 |
| ジョブマトリックス | 256ジョブ/ワークフロー | GitHub-hosted/Self-hosted共通 |
| ジョブ実行時間(Self-hosted) | 5日 | 超過するとジョブが終了 |
| ジョブ実行時間(GitHub-hosted) | 6時間 | 超過するとジョブが終了 |
| ジョブキュー時間 | 24時間 | 自動的にキャンセル |
ワークフロートリガーのレート制限
# リポジトリあたり
1,500イベント / 10秒
この制限に達すると、Webhookイベントによってトリガーされるはずだったワークフローがブロックされます。再利用可能ワークフローは単一のエンティティとしてカウントされます(30の再利用可能ワークフローを使っても1としてカウント)。
Self-hostedランナーの制限
| 制限 | 値 |
|---|---|
| ランナー登録 | 1,500ランナー / 5分 / リポジトリ・組織・エンタープライズ |
| ランナーグループあたり | 10,000ランナー |
GitHub-hostedランナーの並行実行制限
| ランナータイプ | プラン | 総並行ジョブ数 | macOS最大並行数 | GPU最大並行数 |
|---|---|---|---|---|
| 標準ランナー | Free | 20 | 5 | N/A |
| 標準ランナー | Pro | 40 | 5 | N/A |
| 標準ランナー | Team | 60 | 5 | N/A |
| 標準ランナー | Enterprise | 500 | 50 | N/A |
| Larger runner | Team | 1,000 | 5 | 100 |
| Larger runner | Enterprise | 1,000 | 50 | 100 |
Larger Runnerの追加制限
| 項目 | 制限値 |
|---|---|
| ランナーごとの並行実行制限 | ランナータイプによって異なる 通常、Linux CPUランナーは最大1,000だが、タイプにより変動 |
| Static IP制限 | エンタープライズおよび組織ごとに10個 |
| VNet injectionのプライベートIP | 最大ジョブ並行実行数の30%バッファが必要 |
VNet injectionを使用する場合、サブネットIPアドレス範囲の計画が重要です。例えば、最大ジョブ並行実行数が300の場合、少なくとも390のランナーを収容できるサブネット範囲が必要です。なお、Azureはすべてのサブネットで5つのIPアドレスを予約します(最初の4つと最後の1つ)。
ストレージ制限
| プラン | アーティファクトストレージ | 分数(月間) | キャッシュストレージ |
|---|---|---|---|
| GitHub Free | 500 MB | 2,000分 | 10 GB |
| GitHub Pro | 1 GB | 3,000分 | 10 GB |
| GitHub Free(組織) | 500 MB | 2,000分 | 10 GB |
| GitHub Team | 2 GB | 3,000分 | 10 GB |
| GitHub Enterprise Cloud | 50 GB | 50,000分 | 10 GB |
注意:GitHubサポートはストレージ制限の引き上げには対応していません。
REST APIのレート制限
GitHub Actionsユーザーにも、GitHubのREST APIレート制限が適用されます。これらの制限は、ワークフロー内でAPIを呼び出す際に影響します。
未認証リクエスト:パブリックデータのみ取得可能で、IPアドレスごとに60リクエスト/時に制限されます。
認証済みユーザー:Personal Access Token(PAT)を使用すると5,000リクエスト/時。GitHub Enterprise Cloud組織の場合は15,000リクエスト/時。
GitHub Appインストール:インストールアクセストークンを使用する場合、最小5,000リクエスト/時。GitHub Enterprise Cloud組織では15,000リクエスト/時。インストールがGHEC組織以外の場合、ユーザー数とリポジトリ数に応じてスケールします:
- 20以上のリポジトリ:リポジトリごとに50リクエスト/時を追加
- 20以上のユーザー:ユーザーごとに50リクエスト/時を追加
- 上限:12,500リクエスト/時
OAuth Apps:5,000リクエスト/時。GitHub Enterprise Cloud組織所有の場合は15,000リクエスト/時。
GITHUB_TOKEN:1,000リクエスト/時/リポジトリ。GitHub Enterprise Cloudアカウントのリソースへのリクエストの場合は15,000リクエスト/時/リポジトリ。
セカンダリレート制限
プライマリレート制限に加えて、GitHubは悪用防止のためにセカンダリレート制限を適用します。これらは設定変更できません。過度に高速なリクエストや大量のリクエストを送信すると、プライマリレート制限に達していなくても一時的にブロックされる可能性があります。
Docker Hubのレート制限
- GitHub-hostedランナー(パブリックイメージ): レート制限なし
- GitHub-hostedランナー(プライベートイメージ): レート制限あり
- Self-hostedランナー(すべて): レート制限あり
8. 既存CI/CDからの移行戦略
GitHub Actions Importerは、既存のCI/CDシステムからGitHub Actionsへの移行を支援するツールです。
移行プロセスの概要
カスタムトランスフォーマーの活用
GitHub Actions Importerは、移行プロセスをカスタマイズするための拡張機能を提供します。
1. ビルドステップのカスタム変換
独自のビルドステップやプラグインをGitHub Actionsに変換する例:
# transformers.rb
transform "buildJavaScriptApp" do |item|
command = ["build", "package", "deploy"].map do |script|
"npm run #{script}"
end
{
name: "JavaScriptアプリのビルド",
run: command.join("\n")
}
end
変換後のワークフロー:
- name: "JavaScriptアプリのビルド"
run: |
npm run build
npm run package
npm run deploy
2. ランナーラベルのマッピング
既存のCI/CDシステムのランナーラベルをGitHub Actionsのランナーに変換:
# 単一ラベルのマッピング
runner "linux", "ubuntu-latest"
# 複数ラベルへのマッピング
runner "big-agent", ["self-hosted", "xl", "linux"]
# デフォルトランナーの変更
runner :default, "macos-latest"
3. 環境変数の変換
# 既存の環境変数を新しい値に変換
env "OCTO", "CAT"
# 環境変数を削除
env "MONA_LISA", nil
# 環境変数をシークレットにマッピング
env "MONALISA", secret("OCTOCAT")
# 正規表現で複数の環境変数を一括変換
env /^(.+)_SSH_KEY$/, secret("%s_SSH_KEY")
補足的な引数と設定
GitHub Actions Importerには、移行プロセスをカスタマイズするための様々なオプションがあります。
パス引数の扱い
GitHub Actions Importerを実行する際、パス引数はコンテナのディスクに対する相対パスとして扱われます。コンテナの/dataディレクトリは、GitHub Actions Importerを実行したディレクトリにマウントされます。
例えば、/Users/tanakaディレクトリで以下のコマンドを実行すると、監査サマリーは/Users/tanaka/outディレクトリに出力されます:
gh actions-importer audit --output-dir /data/out
ネットワークレスポンスキャッシュの無効化
デフォルトでは、GitHub Actions Importerはネットワークリクエストのレスポンスをキャッシュして、ネットワーク負荷と実行時間を削減します。--no-http-cacheオプションでキャッシュを無効化できます:
gh actions-importer forecast ... --no-http-cache
SSL証明書検証の無効化
デフォルトでは、GitHub Actions ImporterはネットワークリクエストでSSL証明書を検証します。--no-ssl-verifyオプションで検証を無効化できます:
gh actions-importer audit --output-dir ./output --no-ssl-verify
許可するアクションの制限
# 特定のアクションのみ許可
gh actions-importer migrate ... \
--allowed-actions actions/checkout@v4 actions/upload-artifact@* my-org/*
# すべてのアクションを禁止
gh actions-importer migrate ... --allowed-actions=
# 検証済み作成者のアクションを許可
gh actions-importer migrate ... --allow-verified-actions
# GitHubとactionsオーガニゼーションのアクションを許可
gh actions-importer migrate ... --allow-github-created-actions
認証情報ファイルの使用
複数のGitHub Enterprise Serverインスタンスやソースコードプロバイダーにアクセスする場合:
# credentials.yml
- url: https://github.com
access_token: ghp_generaltoken
- url: https://github.com/specific_org/
access_token: ghp_orgtoken
- url: https://jenkins.org
access_token: abc123
username: tanaka_taro
- url: https://gitlab.com
access_token: super_secret_token
provider: gitlab
使用方法:
gh actions-importer migrate ... --credentials-file credentials.yml
機能フラグの制御
古いGitHub Enterprise Serverバージョンへ移行する場合、新しい構文を除外できます:
# GHES 3.3向けに機能を制限
gh actions-importer migrate ... --features ghes-3.3
# 利用可能な機能フラグを一覧表示
gh actions-importer list-features
# 特定の機能を有効化/無効化
gh actions-importer migrate ... \
--disable-features composite-actions actions/cache
プロキシ設定
HTTPプロキシ経由でアクセスする場合:
export OCTOKIT_PROXY=https://proxy.example.com:8443
export HTTPS_PROXY=$OCTOKIT_PROXY
gh actions-importer migrate ...
認証が必要な場合:
export OCTOKIT_PROXY=https://username:password@proxy.example.com:8443
9. セキュリティ機能の総合活用
GitHub Actionsには、ワークフローのセキュリティを高めるための多数の機能が組み込まれています。
Dependabotによる自動更新
Dependabotは、アクションと再利用可能ワークフローを最新バージョンに保つための機能です。
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "github-actions"
Dependabotは以下をサポートします:
- バージョン更新のプルリクエスト作成
- セキュリティアドバイザリ対応の自動PR作成
- パブリック/プライベートリポジトリ両方
注意:Dependabotは以下には対応していません:
-
docker://構文のDockerコンテナアクション - Docker HubやGitHub Packages Container registryのURL
Dependency Reviewによる変更の検証
プルリクエストでアクションの変更を検証できます:
name: "依存関係レビュー"
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
このアクションは、プルリクエストで導入される脆弱性のあるアクションを検出し、警告します。
Code Scanningでワークフローを検証
Code Scanningは、GitHub Actionsワークフローの一般的な脆弱性パターンを自動検出します。
name: "CodeQL"
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
steps:
- uses: actions/checkout@v4
- name: "CodeQL初期化"
uses: github/codeql-action/init@v3
with:
languages: javascript
queries: security-and-quality
- name: "CodeQL分析実行"
uses: github/codeql-action/analyze@v3
CODEOWNERSで変更を監視
ワークフローファイルへの変更を制御するために、CODEOWNERSファイルを使用できます:
# .github/CODEOWNERS
/.github/workflows/ @組織名/セキュリティチーム @組織名/devopsチーム
これにより、ワークフローファイルの変更には指定されたレビュアーの承認が必要になります。
OpenSSF Scorecardsでサプライチェーンを強化
Scorecardsは、リポジトリのセキュリティリスクを評価する自動化ツールです:
name: "Scorecards"
on:
branch_protection_rule:
schedule:
- cron: '0 3 * * 1'
push:
branches: [main]
permissions: read-all
jobs:
analysis:
runs-on: ubuntu-latest
permissions:
security-events: write
id-token: write
steps:
- uses: actions/checkout@v4
- name: "Scorecards分析実行"
uses: ossf/scorecard-action@v2
with:
results_file: results.sarif
results_format: sarif
- name: "結果をアップロード"
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
Scorecardsは以下をチェックします:
- スクリプトインジェクション攻撃のリスク
- トークン権限の設定
- アクションのピン留め状態
- その他のサプライチェーンリスク
まとめ
GitHub Actionsは非常に強力なCI/CDプラットフォームですが、その力を安全に、効率的に使うには、以下の原則を守ることが重要です。
セキュリティのチェックリスト
-
GITHUB_TOKENの権限は最小限に設定 - シークレットは環境変数経由で参照
- 構造化データはシークレットにしない
- スクリプトインジェクション対策を実装
- サードパーティアクションは完全なコミットSHAでピン留め
- OIDCで長期認証情報を排除
- Self-hostedランナーはパブリックリポジトリで使用しない
- Dependabotで依存関係を自動更新
- Code ScanningとDependency Reviewを有効化
- CODEOWNERSでワークフローファイルを保護
スケーラビリティのチェックリスト
- レート制限を理解し、監視
- 並行実行数の上限を把握
- ストレージ使用量を定期的に確認
- 必要に応じてGitHubサポートに制限緩和を依頼
- ワークフロートリガーの頻度を最適化
- キャッシュとアーティファクトのライフサイクルを管理
移行のチェックリスト
- GitHub Actions Importerで監査を実施
- カスタムトランスフォーマーで独自ロジックを変換
- ドライランで変換結果を検証
- 段階的に移行を実施
- 移行後もワークフローを継続的に改善
GitHub Actionsを正しく理解し、適切に実装することで、安全で効率的な、そして拡張性の高いCI/CDパイプラインを構築できます。本記事が、皆さんのGitHub Actions活用の一助となれば幸いです。