Skip to main content

クラウド プロバイダーでの OpenID Connect の構成

ワークフロー内で OpenID Connect を使用して、クラウド プロバイダーでの認証を行います。

概要

OpenID Connect (OIDC) を使用すると、GitHub Actions ワークフローでは、有効期間の長い GitHub シークレットとして資格情報を格納しなくても、クラウド プロバイダー内のリソースにアクセスできます。

OIDC を使用するには、まず、GitHub の OIDC をフェデレーション ID として信頼するようにクラウド プロバイダーを構成してから、トークンを使用して認証するようにワークフローを更新する必要があります。

前提条件

  • GitHub が OpenID Connect (OIDC) を使用する方法の基本的な概念とそのアーキテクチャと利点については、「OpenID Connect を使ったセキュリティ強化について」を参照してください。

  • 先に進む前に、アクセス トークンが予測可能な方法でのみ割り当てられるようにセキュリティ戦略を計画する必要があります。 クラウド プロバイダーがアクセス トークンを発行する方法を制御するには、少なくとも 1 つの条件を定義し、信頼できないリポジトリがクラウド リソースにアクセス トークンを要求できないようにする必要があります。 詳しくは、「OpenID Connect を使ったセキュリティ強化について」を参照してください。

GitHub Actions ワークフローを更新する

OIDC のワークフローを更新するには、YAML に 2 つの変更を行う必要があります。

  1. トークンのアクセス許可設定を追加します。
  2. クラウド プロバイダーの公式アクションを使用して、OIDC トークン (JWT) をクラウド アクセス トークンと交換します。

クラウド プロバイダーでまだ公式アクションを提供していない場合は、ワークフローを更新して手動でこれらの手順を実行できます。

独自のカスタム保護規則を有効にして、サードパーティ サービスを使ったデプロイを制御できます。 たとえば、Datadog、Honeycomb、ServiceNow などのサービスを使用し、GitHub への展開に対して自動承認を提供できます。

アクセス許可設定の追加

ジョブまたはワークフローの実行には、GitHub の OIDC プロバイダーが実行ごとに JSON Web Token を作成できるようにするために、id-token: write を含む permissions 設定が必要です。 id-tokenpermissionswrite に設定されていない場合、OIDC JWT ID トークンを要求することはできません。ただし、この値はリソースへの書き込みアクセスを許可することを意味せず、アクションまたはステップの OIDC トークンをフェッチして設定し、有効期間の短いアクセス トークンを使用して認証を有効にできるだけです。 実際の信頼の設定は OIDC 要求を使用して定義されます。詳細については、「OpenID Connect を使ったセキュリティ強化について」を参照してください。

この id-token: write 設定により、次のいずれかの方法を使用して、GitHub の OIDC プロバイダーから JWT を要求できます。

  • ランナーで環境変数を使用する (ACTIONS_ID_TOKEN_REQUEST_URL および ACTIONS_ID_TOKEN_REQUEST_TOKEN)。
  • アクション ツールキットから getIDToken() を使用する。

ワークフローの OIDC トークンをフェッチする必要がある場合は、ワークフロー レベルでアクセス許可を設定できます。 次に例を示します。

YAML
permissions:
  id-token: write # This is required for requesting the JWT
  contents: read  # This is required for actions/checkout

1 つのジョブに対して OIDC トークンのみをフェッチする必要がある場合は、そのジョブ内でこのアクセス許可を設定できます。 次に例を示します。

YAML
permissions:
  id-token: write # This is required for requesting the JWT

ワークフローの要件に応じて、ここで追加のアクセス許可を指定する必要がある場合があります。

呼び出し元ワークフローと同じユーザー、Organization、または Enterprise が所有する再利用可能なワークフローの場合、再利用可能なワークフローで生成された OIDC トークンに呼び出し元のコンテキストからアクセスできます。 Enterprise または Organization 外部の再利用可能なワークフローについては、id-tokenpermissions 設定を、呼び出し元ワークフロー レベル、または再利用可能ワークフローを呼び出す特定のジョブで write に設定してください。 これにより、再利用可能なワークフローで生成された OIDC トークンは、意図した場合にのみ呼び出し元ワークフローで使用できるようになります。

詳しくは、「ワークフローの再利用」を参照してください。

公式アクションの使用

クラウド プロバイダーが、GitHub Actions で OIDC を使用するための公式アクションを作成している場合は、OIDC トークンをアクセス トークンと簡単に交換できます。 その後、クラウド リソースにアクセスするときにこのトークンを使用するようにワークフローを更新できます。

たとえば、Alibaba Cloud は、OIDC と GitHub を使用して統合するために aliyun/configure-aliyun-credentials-action 作成されました。

カスタム アクションの使用

クラウド プロバイダーに公式アクションがない場合、またはカスタム スクリプトを作成する場合は、GitHub の OIDC プロバイダーから JSON Web トークン (JWT) を手動で要求できます。

公式アクションを使用していない場合、GitHub では Actions コア ツールキットを使用することをお勧めします。 または、次の環境変数を使用して、ACTIONS_ID_TOKEN_REQUEST_TOKENACTIONS_ID_TOKEN_REQUEST_URL トークンを取得できます。

このアプローチを使用してワークフローを更新するには、YAML に 3 つの変更を加える必要があります。

  1. トークンのアクセス許可設定を追加します。
  2. OIDC トークンを要求するコードを、GitHub の OIDC プロバイダーに追加します。
  3. OIDC トークンをクラウド プロバイダーで交換してアクセス トークンを取得するコードを追加します。

Actions コア ツールキットを使用した JWT の要求

次の例では、core ツールキットで actions/github-script を使用して、GitHub の OIDC プロバイダーから JWT を要求する方法を示します。 詳しくは、「JavaScript アクションを作成する」をご覧ください。

jobs:
  job:
    environment: Production
    runs-on: ubuntu-latest
    steps:
    - name: Install OIDC Client from Core Package
      run: npm install @actions/core@1.6.0 @actions/http-client
    - name: Get Id Token
      uses: actions/github-script@v6
      id: idtoken
      with:
        script: |
          const coredemo = require('@actions/core')
          let id_token = await coredemo.getIDToken()
          coredemo.setOutput('id_token', id_token)

環境変数を使用した JWT の要求

次の例では、環境変数を使用して JSON Web トークンを要求する方法を示します。

デプロイ ジョブでは、core ツールキットで actions/github-script を使用して、トークン設定を定義する必要があります。 詳しくは、「JavaScript アクションを作成する」をご覧ください。

次に例を示します。

jobs:
  job:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/github-script@v6
      id: script
      timeout-minutes: 10
      with:
        debug: true
        script: |
          const token = process.env['ACTIONS_RUNTIME_TOKEN']
          const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']
          core.setOutput('TOKEN', token.trim())
          core.setOutput('IDTOKENURL', runtimeUrl.trim())

その後、GitHub OIDC プロバイダーから JWT を取得するために curl を使用できます。 次に例を示します。

    - run: |
        IDTOKEN=$(curl -H "Authorization: bearer  ${{steps.script.outputs.TOKEN}}" ${{steps.script.outputs.IDTOKENURL}}  -H "Accept: application/json; api-version=2.0" -H "Content-Type: application/json" -d "{}" | jq -r '.value')
        echo $IDTOKEN
        jwtd() {
            if [[ -x $(command -v jq) ]]; then
                jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< "${1}"
                echo "Signature: $(echo "${1}" | awk -F'.' '{print $3}')"
            fi
        }
        jwtd $IDTOKEN
        echo "idToken=${IDTOKEN}" >> $GITHUB_OUTPUT
      id: tokenid

クラウド プロバイダーからのアクセス トークンの取得

アクセス トークンを取得するには、OIDC JSON Web トークンをクラウド プロバイダーに提示する必要があります。

デプロイごとに、ワークフローでは、OIDC トークンをフェッチしてクラウド プロバイダーに提示するクラウド ログイン アクション (またはカスタム スクリプト) を使用する必要があります。 その後、クラウド プロバイダーではトークン内の要求を検証します。成功した場合は、そのジョブ実行でのみ使用できるクラウド アクセス トークンが提供されます。 提供されたアクセス トークンは、ジョブ内の後続のアクションでクラウドに接続し、そのリソースにデプロイするために使用できます。

OIDC トークンをアクセス トークンと交換する手順は、クラウド プロバイダーごとに異なります。

クラウド プロバイダー内のリソースへのアクセス

アクセス トークンを取得したら、特定のクラウド アクションまたはスクリプトを使用して、クラウド プロバイダーに対する認証を行い、そのリソースにデプロイできます。 これらの手順は、クラウド プロバイダーごとに異なる場合があります。

たとえば、Alibaba Cloud は OIDC 認証に関する独自の手順を保持しています。 詳細については、「Alibaba Cloud のドキュメントで OIDC ベースの SSO の概要」を参照してください。

さらに、このアクセス トークンの既定の有効期限は、クラウドごとに異なる場合があり、クラウド プロバイダー側で構成できます。

参考資料