Start Building for Free
CircleCI.comアカデミーブログコミュニティサポート

ジョブでの OpenID Connect トークンの使用

1 week ago3 min read
クラウド
このページの内容

CircleCI では、 コンテキストを使用するジョブの環境変数で OpenID Connect ID (OIDC) トークンを利用できます。 ジョブは、CircleCI に永続的な認証情報を保存することなく、このトークンを使って互換性のあるクラウドサービスにアクセスすることができます。

OpenID Connect ID トークンの使用方法

1 つ以上のコンテキストを使用する CircleCI ジョブでは、環境変数 $CIRCLE_OIDC_TOKEN および $CIRCLE_OIDC_TOKEN_V2 で OpenID Connect ID トークンを使用することができます。 $CIRCLE_OIDC_TOKEN_V2 トークンの sub クレームの形式は、以下の表に示すとおりこれまでと異なります。

context キーを circleci/config.yml ファイルの workflows セクションに追加して、 ジョブにコンテキストを追加します。

workflows:
  my-workflow:
    jobs:
      - run-tests:
          context:
            - my-context

クラウドサービスの設定

クラウドサービスのドキュメントで、ID プロバイダーの追加方法を確認してください。 たとえば、AWS の場合は「 OpenID Connect (OIDC) ID プロバイダーの作成」、Google Cloud Platform の場合は「 Workload Identity 連携の構成」を参照してください。

OpenID プロバイダーは、組織に一意のものです。 URL は https://oidc.circleci.com/org/<organization_id> で、organization_id は、組織を表す組織 ID (UUID) です。 CircleCI の組織 ID は、 CircleCI Web アプリ[Organization Settings (組織設定)] > [Overview (概要)] で確認できます。

CircleCI が発行した OpenID Connect ID トークンには、固定の audience が設定されています (下記表の aud を参照)。これも組織 ID です。

OpenID Connect ID トークンの形式

OpenID Connect ID トークンには、下記の標準 クレームが含まれています。

クレーム説明

iss

issuer: ジョブが実行されている CircleCI 組織に固有の issuer です。 値は、"https://oidc.circleci.com/org/<organization_id>" という文字列です。organization_id は、現在のジョブのプロジェクトの組織を表す UUID です。

sub

subject: CircleCI ジョブの実行者とその場所を識別します。 $CIRCLE_OIDC_TOKEN_V2 では、変更ソースの情報も含まれます。

$CIRCLE_OIDC_TOKEN の場合、この値は "org/<organization_id>/project/<project_id>/user/<user_id>" という文字列です。organization_idproject_iduser_id はそれぞれ、CircleCI の組織、プロジェクト、ユーザーを表す UUID です。 user は、このジョブを実行した CircleCI ユーザーです。

$CIRCLE_OIDC_TOKEN_V2 の場合、この値は "org/<organization_id>/project/<project_id>/user/<user_id>/vcs-origin/<vcs_origin>/vcs-ref/<vcs_ref>" という文字列です。organization_idproject_iduser_id はそれぞれ、CircleCI の組織、プロジェクト、ユーザーを表す UUID です。 user は、このジョブを実行した CircleCI ユーザーです。 vcs_originvcs_ref はそれぞれ、リポジトリの URL を指す文字列と、ジョブ実行のトリガーとなった変更を指す文字列です。

aud

audience: 現在は、固定の値 "ORGANIZATION_ID" で、ジョブのプロジェクトの組織を表す UUID を含む文字列です。

iat

time of issuance: トークンの作成時刻 (ジョブの開始直前の時刻) です。

exp

expiration time: iat から 1 時間後の値です。

OpenID Connect ID トークンには、ジョブに関する追加のメタデータを含む 追加クレームも含まれています。

追加クレームメタデータ

oidc.circleci.com/project-id

ジョブが実行されているプロジェクトの ID です。 値は、CircleCI プロジェクトを表す UUID を含む文字列です。

oidc.circleci.com/vcs-origin

パイプラインをトリガーしたリポジトリの URL です。 github.com/organization-123/repo-1 のような文字列になります。

oidc.circleci.com/vcs-ref

パイプラインのトリガーとなった変更のリファレンスです。 refs/heads/main のような文字列になります。

oidc.circleci.com/context-ids

ジョブで使用されるコンテキストを表す UUID を要素として持つ文字列の配列です。 現在サポートされているコンテキストは一つのみです。

クラウドプロバイダーを使ったジョブの認証

次のセクションでは、Amazon Web Services (AWS) と Google Cloud Platform (GCP) を使用して CircleCI でジョブを認証する方法を説明します。

AWS

ここでは、AWS について下記の説明をします。

  • CircleCI の OIDC トークンを信頼するよう AWS アカウントのワンタイム設定を行う方法

  • AWS との連携に OIDC トークンを使用するジョブを実行する方法

AWS の設定

AWS アカウントが CircleCI の OpenID Connect トークンを信頼するのを許可する必要があります。 これを行うには、Identity and Access Management (IAM) ID プロバイダーと AWS の IAM ロール (ワンタイム設定) を作成します。

AWS ドキュメントの「 OpenID Connect (OIDC) ID プロバイダーの作成」を参照し、指示に従います。 CircleCI の組織 ID が必要になります。この ID を見つけるには、https://app.circleci.com/[CircleCI Web アプリ]で [Organization Settings (組織設定)] > [Overview (概要)] に移動します。 次のステップで使用するために組織 ID をコピーします。

Provider URL を求められたら、https://oidc.circleci.com/org/<organization_id> と入力します。organization_id には、CircleCI の組織 ID を入力します。 [Audience] にも同じ CircleCI 組織 ID を入力します。

次に、IAM ロールを作成します。 AWS ドキュメントの「 ウェブ ID または OIDC 用のロールの作成」を開きます。

信頼済みエンティティには [Web Identity] を選択し、先ほど作成した ID プロバイダーを選択します。 [Audience] には、唯一のオプションを選択します。 次に [NEXT] をクリックします。[Add Permissions] ページに移動します。 ここでは、CircleCI ジョブに許可する処理と許可しない処理を指定できます。 AWS のベストプラクティスに従い、ジョブに必要なアクセス許可だけを選択するようにしてください。

注: 独自のポリシーを作成すると便利な場合があります。

CircleCI コンフィグファイルへの AWS の追加

IAM ロールのセットアップが完了したので、OIDC により AWS との認証を行う CircleCI ジョブを作成しましょう。 具体的には、CircleCI の AWS CLI Orb を使用して、一時キーの生成および OIDC を利用するプロファイルの設定を行います。 Orb とは、繰り返し利用する構成内容を 1 行のコードにまとめて再利用可能にした、YAML コンフィグファイルのパッケージです。 今回使用する AWS CLI Orb では、コンフィグファイルに 1 コマンドを記述するだけで、一時セッショントークン、AWS アクセスキー ID、AWS シークレットアクセスキーを生成できます。

まず、ワークフローの CircleCI ジョブのうち、OIDC を使用するものを選択します。 OIDC を使用するジョブには、有効なコンテキストを用意してください。 OpenID Connect トークンを使用できるのは、少なくとも 1 つのコンテキストを使用するジョブだけだからです。 この場合のコンテキストは、環境変数を設定しなくてもかまいません。

.circleci/config で、aws-cli Orb をインポートします。 次に、ジョブ内でいずれかの AWS サービスを利用する前に aws-cli/setup コマンドを実行します。 aws-cli/setup コマンドには、前述の手順で作成したロールに関連する role-arnaws-region を指定する必要があります。

また、任意で、profile-namerole-session-namesession-duration を指定します。 profile-name を指定すると、指定したプロファイルに応じて一時キーとトークンが設定されます。 指定する profile-name は、他の AWS コマンドと揃える必要があります。 profile-name を指定しない場合、キーとトークンはデフォルトプロファイルにあわせてされます。

さらに、role-session-name または session-duration を指定しない場合、それぞれデフォルト値の ${CIRCLE_JOB} (ジョブ名) と 3600 秒に設定されます。

以下に示すコンフィグファイルのサンプルでは、OIDC を使用するプロファイルを構成してからそのプロファイルで AWS ECR にログインするジョブを設定しています。 role-arn に適切な権限を設定していれば、このプロファイルを使用して S3 や EKS、ECS などの他の AWS コマンドも実行できます。

version: '2.1'
orbs:
  # import CircleCI's aws-cli orb
  aws-cli: circleci/aws-cli@3.1
jobs:
  aws-example:
   environment:
      AWS_REGION: us-west-1
    docker:
      - image: cimg/aws:2022.06
    steps:
      - checkout
      # run the aws-cli/setup command from the orb
      - aws-cli/setup:
          role-arn: "arn:aws:iam::123456789012:role/OIDC-ROLE"
          aws-region: AWS_REGION
          # optional parameters
          profile-name: "OIDC-PROFILE"
          role-session-name: "example-session"
          session-duration: "1800"
      - run:
        name: Log-into-AWS-ECR
        command: |
          # must use same profile specified in the step above
          aws ecr get-login-password --profile "OIDC-PROFILE"
workflows:
  OIDC-with-AWS:
    jobs:
      - aws-example:
          # must use a valid CircleCI context
          context: aws

高度な設定

CircleCI の OIDC token のクレーム形式を使って、AWS で CircleCI ジョブができることを制限することができます。

プロジェクトに応じたロールアクセスの制限

たとえば、特定のプロジェクトが特定の AWS リソースにのみアクセスできるようにする場合、特定のプロジェクトの CircleCI ジョブのみがそのロールを担えるように IAM ロールを制限できます。

これを行うには、IAM ロールの信頼ポリシーを編集して、選択したプロジェクトの OIDC トークンのみがその役割を担うようにします。 信頼ポリシーにより、どのような条件下でロールを担えるのかが決定します。

  1. CircleCI Web アプリで目的のプロジェクトのページに移動して、[Project Settings (プロジェクト設定)] > [Overview (概要)] でプロジェクト ID を確認します。

  2. ロールの信頼ポリシーに以下の条件を追加し、選択したプロジェクトのジョブのみがロールを担えるようにします。 organization_id には組織 ID、project_id にはプロジェクト ID を入力します。

    "StringLike": {
      "oidc.circleci.com/org/<organization_id>:sub": "org/<organization_id>/project/<project_id>/user/*"
    }

    これは StringLike を使って、選択したプロジェクトの CircleCI の OIDC トークンのサブクレームを照合します。 これで、他のプロジェクトのジョブは、このロールを担えないようになりました。

ブランチに応じたロールアクセスの制限

指定したブランチへのアクセスを制限することもできます。 以下に示す信頼ポリシーのサンプルでは、AssumeRoleWithWebIdentity アクションの使用を、ID が organization_id である GitHub 組織 (CircleCI 組織) my-orgmain ブランチで実行されるプロジェクトパイプラインのみに制限しています。 なお、sub クレームでは、$CIRCLE_OIDC_TOKEN_V2 形式を使用しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.circleci.com/org/<organization_id>"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "oidc.circleci.com/org/<organization_id>:sub": "org/<organization_id>/project/*/user/*/vcs-origin/github.com/my-org/*/vcs-ref/refs/heads/main"
                }
            }
        }
    ]
}

Google Cloud Platform

ここでは、GCP について下記の説明をします。

  • CircleCI の OIDC トークンを信頼するよう GCP 設定のワンタイム設定を行う方法

  • GCP との連携に OIDC トークンを使用するジョブを実行する方法

Google Cloud CLI はコンフィグファイルを読み込みます。このファイルには Google Cloud で認証を行うために必要な情報が含まれます。 外部の ID プロバイダーについては Google Cloud のドキュメント で確認できます。

GCP のセットアップ

GCP 設定ファイルは GCP Web UI を使用してセットアップできます。 [Workload Identity Federation UI][Grant Access] に移動します。ここで求められる設定は、後からダウンロードできます。 CIRCLE_OIDC_TOKEN_FILE という名前のファイルを作成する必要があります。ここから Google Cloud が ID トークンを読み取ります (ファイル名は、credential_source の設定内容と一致していれば任意の名前にできます)。

CircleCI の組織 ID が必要になります。この ID を見つけるには、https://app.circleci.com/[CircleCI Web アプリ]で [Organization Settings (組織設定)] > [Overview (概要)] に移動します。

GCP Web UI の Grant Access セクションに移動したら、次の手順を実行して CircleCI を外部 ID プロバイダーとして追加します。

  1. IAM & Admin Panel に移動します。

  2. サイドパネルで [Workload Identity Federation] に移動します。

  3. [Add Provider] ボタンをクリックします。

  4. [Select a provider] ドロップダウンから [OpenID Connect (OIDC)] を選択して [Save] をクリックします。

  5. [Provider details] フォームに入力します。

    • JSON Web トークンの aud クレームが UUID (CircleCI 組織 ID) であるため、[Allowed audiences] を選択します。 audience は CircleCI 組織 ID にします。

    • issuer は https://oidc.circleci.com/org/<organization_id> です。organization_id には CircleCI 組織 ID を入力します。

  6. [Continue] をクリックしてプロバイダー属性を設定します。

    プロバイダー属性を設定すると、CircleCI のトークンに含まれるクレームを Google の "解釈" にマッピングできます。 たとえば以下のようになります。

    google.subject

    attribute.project_id

    attribute.org_id

    assertion.aud

    assertion.sub

    assertion['oidc.circleci.com/project-id']

  7. IAM & Admin Panel の [Service Account] に移動して、サービスアカウントを作成して適切なアクセス許可を付与します。

  8. [Workload Identity Federation] に戻って表からプロバイダーを選択します。

  9. [Grant access] ボタンをクリックします。

  10. モーダルが表示され、作成したサービスアカウントをドロップダウンから選択します。 これが、トークンで使用されるアカウントで、関連付けられたすべてのアクセスが許可されます。

  11. [Select principals] で条件を追加するか、デフォルトのままにできます。

  12. [Save] をクリックします。 設定の実施とコンフィグファイルのダウンロードを求めるポップアップが表示されます。 このファイルは、[Connected Service Accounts] に移動すると後でダウンロードすることもできます。

  13. ダウンロードしたコンフィグファイルをリポジトリに保存します。 このファイルは CircleCI 設定で参照します。

コンフィグファイルのサンプルを以下に示します。 audience の次の情報がまだ設定されていないことに注意してください。

  • project_number (プロジェクト用に生成された一意の識別番号)

  • pool_id (ワークロード ID プールを参照する ID。circleci_oidc など)

  • provider_id (ワークロード ID プールプロバイダーを参照する ID。circleci など)

 {
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/<project_number>/locations/global/workloadIdentityPools/<pool_id>/providers/<provider_id>",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "token_url": "https://sts.googleapis.com/v1/token",
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/circleci-test@incubator-344312.iam.gserviceaccount.com:generateAccessToken",
  "credential_source": {
    "file": "CIRCLE_OIDC_TOKEN_FILE",
    "format": {
      "type": "text"
    }
  }
}

この設定で、credential_sourceCIRCLE_OIDC_TOKEN_FILE ファイル内で ID トークンの検出を試みます。

トークンが API レスポンスに基づいている場合、JSON ファイルを読み取るように設定をセットアップすると便利です。 この場合、typejson に設定し、有効な path を指定する必要があります (例: response.id_token)。

  "credential_source": {
    "file": "CIRCLE_OIDC_TOKEN_FILE",
    "format": {
      "type": "json",
      "path": "response.id_token"
    }
  }

必要に応じて、次のスクリプトを実行して GCP コンフィグファイルを生成することもできます。

gcloud iam workload-identity-pools create-cred-config \
  "${GCP_WORKLOAD_IDENTITY_POOL_AUDIENCE}" \
  --output-file="${GCP_CREDENTIAL_CONFIGURATION_FILE}" \
  --service-account="${GCP_SERVICE_ACCOUNT_EMAIL}" \
  --credential-source-file="${GCP_CREDENTIAL_SOURCE_FILE}"

CircleCI コンフィグファイルへの GCP の追加

次のように実行して、$CIRCLE_OIDC_TOKENCIRCLE_OIDC_TOKEN_FILE という名前のファイルにエクスポートする必要があります。

echo $CIRCLE_OIDC_TOKEN >> CIRCLE_OIDC_TOKEN_FILE

次の環境変数を context に追加する必要もあります。

コンテキスト変数名

サンプル値

備考

GCP_PROJECT_ID

123456789012

GCP プロジェクト番号

GCP_WIP_ID

myworkloadpoolid

ワークロードの ID プールの ID

GCP_WIP_PROVIDER_ID

myproviderid

ワークロードの ID プールプロバイダー名

GCP_SERVICE_ACCOUNT_EMAIL

myserviceacct@myproject.iam.gserviceaccount.com

ユーザー管理サービスアカウント

次に、GCP をジョブに追加し、gcp-oidc-authenticate コマンドを使用して認証するサンプル設定の完全な例を示します。 この例では circleci/gcp-cli Orb を使用します。

version: 2.1

orbs:
  gcp-cli: circleci/gcp-cli@2.4.1

commands:
  gcp-oidc-generate-cred-config-file:
    description: "Authenticate with GCP using a CircleCI OIDC token."
    parameters:
      project_id:
        type: env_var_name
        default: GCP_PROJECT_ID
      workload_identity_pool_id:
        type: env_var_name
        default: GCP_WIP_ID
      workload_identity_pool_provider_id:
        type: env_var_name
        default: GCP_WIP_PROVIDER_ID
      service_account_email:
        type: env_var_name
        default: GCP_SERVICE_ACCOUNT_EMAIL
      gcp_cred_config_file_path:
        type: string
        default: /home/circleci/gcp_cred_config.json
      oidc_token_file_path:
        type: string
        default: /home/circleci/oidc_token.json
    steps:
      - run:
          command: |
            # Store OIDC token in temp file
            echo $CIRCLE_OIDC_TOKEN > << parameters.oidc_token_file_path >>
            # Create a credential configuration for the generated OIDC ID Token
            gcloud iam workload-identity-pools create-cred-config \
                "projects/${<< parameters.project_id >>}/locations/global/workloadIdentityPools/${<< parameters.workload_identity_pool_id >>}/providers/${<< parameters.workload_identity_pool_provider_id >>}"\
                --output-file="<< parameters.gcp_cred_config_file_path >>" \
                --service-account="${<< parameters.service_account_email >>}" \
                --credential-source-file=<< parameters.oidc_token_file_path >>

  gcp-oidc-authenticate:
    description: "Authenticate with GCP using a GCP credentials file."
    parameters:
      gcp_cred_config_file_path:
        type: string
        default: /home/circleci/gcp_cred_config.json
    steps:
      - run:
          command: |
            # Configure gcloud to leverage the generated credential configuration
            gcloud auth login --brief --cred-file "<< parameters.gcp_cred_config_file_path >>"
            # Configure ADC
            echo "export GOOGLE_APPLICATION_CREDENTIALS='<< parameters.gcp_cred_config_file_path >>'" | tee -a "$BASH_ENV"

jobs:
  gcp-oidc-defaults:
    executor: gcp-cli/default
    steps:
      - gcp-cli/install
      - gcp-oidc-generate-cred-config-file
      - gcp-oidc-authenticate
      - run:
          name: Verify that gcloud is authenticated
          environment:
            GCP_SERVICE_ACCOUNT_EMAIL: jennings-oidc-test@makoto-workbench.iam.gserviceaccount.com
          command: gcloud iam service-accounts get-iam-policy "${GCP_SERVICE_ACCOUNT_EMAIL}"

workflows:
  main:
    jobs:
      - gcp-oidc-defaults:
          name: Generate Creds File and Authenticate
          context:
          - gcp-oidc-dev

複数のサービスアカウントを同じ GCP プロジェクトから使用することも、複数の GCP プロジェクトから使用することもできます。 これらの方法と例の詳細は、CircleCI の サンプルリポジトリ で確認できます。


ドキュメントの改善にご協力ください

このガイドは、CircleCI の他のドキュメントと同様にオープンソースであり、 GitHub でご利用いただけます。 ご協力いただき、ありがとうございます。

サポートが必要ですか

CircleCI のサポートエンジニアによる、サービスに関する問題、請求およびアカウントについての質問への対応、設定の構築に関する問題解決のサポートを行っています。 サポートチケットを送信して、CircleCI のサポートエンジニアにお問い合わせください。日本語でお問い合わせいただけます。

または、 サポートサイト から、サポート記事やコミュニティフォーラム、トレーニングリソースをご覧いただけます。