Chapter 09

環境変数とシークレット

FarStep
FarStep
2025.02.11に更新

はじめに

本章では、GitHub Actions における環境変数とシークレットについて学びます。前章までで、ワークフローの基本的な構造や設定方法について理解を深めてきましたが、実際のワークフローでは、様々な設定値や機密情報を扱う必要があります。これらの値を安全かつ効率的に管理するために、GitHub Actions では環境変数とシークレットという二つの重要な機能を提供しています。

環境変数は、ワークフローの実行時に使用される様々な設定値や情報を保持するために使用されます。一方、シークレットは、API キーやパスワードなどの機密情報を安全に管理するための機能です。これらの機能を適切に使用することで、セキュアで柔軟なワークフローを実現することができます。

本章では、まず環境変数の基本的な概念と特徴について学び、その後シークレットの使用方法と安全な管理について理解を深めていきます。これらの知識は、実践的なワークフローを作成する上で不可欠な要素となります。

環境変数とは

環境変数は、ワークフローの実行中に使用できる変数です。これらの変数は、ワークフローの設定値や実行時の情報を保持するために使用されます。GitHub Actions では、デフォルトの環境変数が自動的に設定されるとともに、カスタムの環境変数を定義することもできます。

デフォルトの環境変数には、GitHub Actions の実行環境に関する重要な情報が含まれています。たとえば、GITHUB_WORKSPACE はワークフローが実行されるディレクトリのパスを、GITHUB_REPOSITORY は現在のリポジトリの所有者とリポジトリ名を、GITHUB_SHA は現在のコミットの SHA ハッシュを保持しています。これらの変数は、ワークフローの中で自動的に利用可能となり、特別な設定なしで参照することができます。

また、GitHub Actions では、ワークフローの異なるレベル(ワークフローレベル、ジョブレベル、ステップレベル)で環境変数を定義することができます。これにより、変数のスコープを適切に管理し、必要な場所で必要な値を利用することができます。

環境変数は、主に以下のような用途で使用されます。

  1. ビルド設定の管理:アプリケーションのビルド時に必要な設定値(バージョン番号、ビルドモードなど)を保持します。

  2. 実行環境の制御:テスト環境や本番環境など、異なる環境に応じた設定値を管理します。

  3. パラメータの受け渡し:ステップ間やジョブ間でデータを受け渡すために使用します。

  4. 条件分岐の制御:環境変数の値に基づいて、ワークフローの実行を制御します。

環境変数は、機密性の低い設定値を扱うために使用されます。パスワードや API キーなどの機密情報は、環境変数ではなくシークレットとして管理する必要があります。これは、環境変数の値がワークフローのログに表示される可能性があるためです。機密情報を環境変数として設定すると、セキュリティ上のリスクとなる可能性があります。

環境変数のスコープ

環境変数のスコープとは、その環境変数がアクセス可能な範囲を指します。GitHub Actions では、環境変数は定義された場所によって異なるスコープを持ちます。スコープを理解することで、環境変数を適切に管理し、必要な場所で必要な値を利用することができます。

ワークフローレベルで定義された環境変数は、ワークフロー全体でアクセス可能です。このスコープの環境変数は、ワークフロー内のすべてのジョブとステップから参照することができます。

name: Workflow Level Scope
env:
  GLOBAL_CONFIG: "production"
  API_VERSION: "v1"

jobs:
  first-job:
    runs-on: ubuntu-latest
    steps:
      - name: First step
        run: echo "Config: $GLOBAL_CONFIG"

  second-job:
    runs-on: ubuntu-latest
    steps:
      - name: First step
        run: echo "API Version: $API_VERSION"

ジョブレベルで定義された環境変数は、そのジョブ内でのみアクセス可能です。このスコープの環境変数は、同じジョブ内のすべてのステップから参照できますが、他のジョブからは参照できません。

jobs:
  job1:
    runs-on: ubuntu-latest
    env:
      JOB1_SETTING: "value1"
    steps:
      - name: Access job1 variable
        run: echo "Setting: $JOB1_SETTING"

  job2:
    runs-on: ubuntu-latest
    env:
      JOB2_SETTING: "value2"
    steps:
      - name: Access job2 variable
        run: echo "Setting: $JOB2_SETTING"

ステップレベルで定義された環境変数は、そのステップ内でのみアクセス可能です。このスコープの環境変数は、同じステップ内でのみ使用でき、他のステップからは参照できません。

jobs:
  example-job:
    runs-on: ubuntu-latest
    steps:
      - name: First step
        env:
          STEP1_VAR: "step1-value"
        run: echo "Value in step1: $STEP1_VAR"

      - name: Second step
        env:
          STEP2_VAR: "step2-value"
        run: echo "Value in step2: $STEP2_VAR"

環境変数には優先順位があり、より狭いスコープで定義された環境変数が、より広いスコープで定義された同名の環境変数よりも優先されます。たとえば、ステップレベルで定義された環境変数は、同名のジョブレベルやワークフローレベルの環境変数を上書きします。

name: Variable Override Example
env:
  COLOR: "blue"

jobs:
  test-job:
    runs-on: ubuntu-latest
    env:
      COLOR: "green"
    steps:
      - name: First step
        env:
          COLOR: "red"
        run: echo "Color in step: $COLOR"  # 出力: Color in step: red

      - name: Second step
        run: echo "Color in job: $COLOR"   # 出力: Color in job: green

このように、スコープを適切に使い分けることで、環境変数の値を効果的に管理することができます。スコープを意識することで、変数の競合を防ぎ、意図しない値の上書きを避けることができます。

シークレットとは

シークレットは、GitHub Actions で使用する機密情報を安全に管理するための機能です。API キー、データベースのパスワード、アクセストークンなど、公開してはならない重要な情報を、暗号化された形式で保存し、ワークフロー内で使用することができます。

シークレットは通常の環境変数とは異なり、特別な保護機能を備えています。シークレットとして保存された値は、GitHub のインターフェースで表示されることはなく、ログファイルにも出力されません。これにより、機密情報が誤って外部に漏洩することを防ぐことができます。

シークレットは、リポジトリレベル、環境レベル、組織レベルの三つのスコープで管理することができます。リポジトリレベルのシークレットは、特定のリポジトリのワークフローでのみ使用できます。環境レベルのシークレットは、特定の環境(開発環境や本番環境など)に紐づけられ、その環境でワークフローが実行される場合にのみ使用できます。組織レベルのシークレットは、組織内の複数のリポジトリで共有して使用することができます。

シークレットの主な使用例として、以下のようなものがあります。

  1. デプロイメントの認証情報:クラウドサービスやサーバーへのデプロイ時に必要な認証情報を管理します。

  2. サービスの接続情報:外部サービスの API キーやアクセストークンを安全に保存します。

  3. データベースの接続情報:データベースのユーザー名やパスワードを保護します。

  4. パッケージレジストリの認証情報:プライベートパッケージレジストリへのアクセスに必要な認証情報を管理します。

シークレットの値は、いったん保存すると完全な値を再度表示することはできません。セキュリティの観点から、シークレットの値を更新する場合は、新しい値を再度入力する必要があります。また、シークレットの値は適切なタイミングでローテーション(定期的な更新)を行うことが推奨されます。

シークレットの設定方法

シークレットの設定は、GitHub のウェブインターフェースを通じて行います。リポジトリ、環境、組織のそれぞれのレベルでシークレットを設定することができます。

リポジトリレベルでシークレットを設定する場合は、まずリポジトリの「Settings」タブを開きます。

左側のメニューから「Secrets and variables」セクションの「Actions」を選択します。この画面で「New repository secret」ボタンを選択することで、新しいシークレットを作成することができます。

シークレットを作成する際には、シークレットの名前と値を入力する必要があります。シークレットの名前は、ワークフロー内でこの値を参照する際に使用する識別子となります。名前には英数字とアンダースコアのみを使用でき、数字で始めることはできません。また、GITHUB_ というプレフィックスで始まる名前は予約されているため使用できません。入力した値は暗号化されて保存され、一度保存すると元の値を再度表示することはできません。

環境レベルでシークレットを設定する場合は、まず対象の環境を作成する必要があります。リポジトリの「Settings」から「Environments」を選択し、環境を作成または選択します。環境の設定画面で「Add secret」ボタンを選択することで、その環境専用のシークレットを作成することができます。

組織レベルでシークレットを設定する場合は、組織の「Settings」を開き、「Security」セクションから「Secrets and variables」、「Actions」と選択します。この画面で「New organization secret」ボタンを選択することで、組織全体で使用できるシークレットを作成することができます。組織レベルのシークレットを作成する際には、どのリポジトリがそのシークレットにアクセスできるかを選択することができます。

プライベートリポジトリの場合は、すべてのシークレットへのアクセスが制限されますが、パブリックリポジトリの場合は、そのリポジトリをフォークした人が作成したプルリクエストからのワークフローでは、シークレットにアクセスできないように制限されます。この制限により、機密情報の不正な取得を防ぐことができます。

シークレットの値は、いつでも更新または削除することができます。値を更新する場合は、シークレットの編集画面で新しい値を入力します。シークレットを削除する場合は、シークレットの一覧画面で対象のシークレットの横にある削除ボタンを選択します。

シークレットの利用方法

設定したシークレットは、ワークフロー内で secrets コンテキストを通じて参照することができます。シークレットの値は、${{ secrets.SECRET_NAME }} という形式で参照します。ここで、SECRET_NAME は設定時に指定したシークレットの名前です。

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Access database
        env:
          DB_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
        run: |
          echo "Connecting to database using secure password"
          ./connect-db.sh -p $DB_PASSWORD

この例では、DATABASE_PASSWORD というシークレットの値を環境変数 DB_PASSWORD に設定し、スクリプト内で使用しています。シークレットの値は自動的にマスクされるため、ログに表示されることはありません。

シークレットを使用する際には、ステップ内で環境変数として設定するか、アクションの入力パラメータとして渡すことができます。アクションの入力パラメータとして使用する場合は、with キーワードを使用します。

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"
          token: ${{ secrets.NPM_TOKEN }}

環境レベルのシークレットを使用する場合は、ジョブに environment を指定する必要があります。これにより、そのジョブは指定された環境のシークレットにアクセスできるようになります。

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy to production
        env:
          API_KEY: ${{ secrets.PROD_API_KEY }}
          DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}
        run: |
          echo "Deploying to production server"
          ./deploy.sh -k $API_KEY -t $DEPLOY_TOKEN

組織レベルのシークレットを使用する場合も、通常のシークレットと同じように secrets コンテキストを通じてアクセスできます。

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Use organization secret
        env:
          LICENSE_KEY: ${{ secrets.ORGANIZATION_LICENSE_KEY }}
        run: |
          echo "Using organization-wide license key"
          ./activate-license.sh $LICENSE_KEY

シークレットを必要とするアクションを使用する場合は、そのアクションのドキュメントに従って適切な方法でシークレットを渡す必要があります。

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy to Azure
        uses: azure/webapps-deploy@v2
        with:
          app-name: "my-app"
          package: "."

このように、シークレットは様々な方法で利用することができ、それぞれのユースケースに応じて適切な方法を選択することが重要です。

シークレットのセキュリティ

シークレットのセキュリティは、ワークフローの安全な実行において非常に重要な要素です。GitHub Actions には、シークレットを保護するための複数のセキュリティ機能が組み込まれています。

シークレットの値は、保存時に自動的に暗号化されます。暗号化されたシークレットは、ワークフローの実行時にのみ復号化され、ランナー上で使用可能になります。また、シークレットの値はログに出力されないようにマスクされ、アスタリスク(***)で表示されます。

jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: Use secret
        env:
          TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          echo "Token value: $TOKEN"  # 出力: Token value: ***

パブリックリポジトリにおけるフォークされたリポジトリからのプルリクエストでは、デフォルトでシークレットへのアクセスが制限されます。これは、悪意のあるユーザーがプルリクエストを通じてシークレットを取得することを防ぐためです。

jobs:
  test:
    runs-on: ubuntu-latest
    if: github.event.pull_request.head.repo.full_name == github.repository
    steps:
      - name: Protected step
        env:
          SECRET_VALUE: ${{ secrets.PROTECTED_SECRET }}
        run: ./protected-script.sh

シークレットの名前には特定の制限があり、英数字とアンダースコアのみを使用できます。また、GITHUB_ で始まる名前は予約されているため使用できません。これらの制限により、シークレットの名前の衝突や誤用を防ぐことができます。

jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: Valid secret name
        env:
          VALID_SECRET: ${{ secrets.MY_API_KEY }} # 有効
          # GITHUB_SECRET: ${{ secrets.GITHUB_KEY }}   # 無効:GITHUB_ プレフィックス
          # INVALID-SECRET: ${{ secrets.MY-KEY }}      # 無効:ハイフンを含む

おわりに

本章では、GitHub Actions における環境変数とシークレットについて学びました。環境変数は、ワークフローの実行時に必要な設定値や情報を保持するための基本的な機能であり、ワークフロー、ジョブ、ステップの各レベルで定義できることを理解しました。

また、シークレットは機密情報を安全に管理するための重要な機能であり、リポジトリ、環境、組織の各レベルで設定できることを学びました。シークレットの設定方法、利用方法、そしてセキュリティについての理解を深めることで、安全なワークフローの実装が可能になります。

これらの知識は、実践的なワークフローを作成する上で不可欠な要素となります。次章からは、GitHub Actions のより高度な機能について学んでいきます。