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

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

2 weeks ago3 min read
クラウド
このページの内容

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

OpenID Connect ID トークンの使用

1 つ以上のコンテキストを使用する CircleCI ジョブでは、環境変数 $CIRCLE_OIDC_TOKEN で OpenID Connect ID トークンを使用することができます。

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

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

クラウドサービスの設定

クラウドサービスのドキュメントで、ID プロバイダの追加方法を確認してください。 たとえば、AWS の場合は、 Creating OpenID Connect (OIDC) identity providers、Google Cloud Platform の場合は、 Configuring workload identity federation を参照してください。

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 ジョブの実行者とその場所を識別します。 値は、"org/ORGANIZATION_ID/project/PROJECT_ID/user/USER_ID" という文字列です。ORGANIZATION_IDPROJECT_ID、および USER_ID は、それぞれ、CircleCI の組織、プロジェクト、ユーザーを表す UUID です。 ユーザーは、このジョブを実行した CircleCI ユーザーです。

aud

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

iat

time of issuance: トークンが作成された時刻で、ジョブが開始される直前です。

exp

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

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

追加クレームメタデータ

oidc.circleci.com/project-id

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

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 のドキュメントの Creating OpenID Connect (OIDC) identity providers を開き、指示に従います。 CircleCI の組織 ID が必要になります。この ID を見つけるには、 CircleCI Web アプリOrganization Settings > Overview に移動します。 次のステップで使用するために組織 ID をコピーします。

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

次に、IAM ロールを作成します。 AWS のドキュメントの Creating a role for web identity or OIDC を開きます。

信頼されたエンティティには、Web Identity を選択し、先程作成した ID プロバイダを選択します。 Audience には、唯一のオプションを選択します。 次に NEXT をクリックします。Add Permissions のページに移動します。 これで、CircleCI ジョブに許可する処理と許可しない処理を指定できます。 ジョブに必要な権限のみを選択します。これが AWS のベストプラクティス です。

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

CircleCI 設定ファイルへの AWS の追加

これで OpenID Connect トークンを受け取るワークフロー内の CircleCI ジョブを選択する準備が整いました。 OpenID Connect トークンは、1 つ以上の コンテキスト を使用するジョブに対してのみ使用できるため、OIDC トークンを受け取る各ジョブがコンテキスト (環境変数を含まない場合もある) を使用していることを確認してください。

ジョブでは、AWS STS の AssumeRoleWithWebIdentity を実行するために OpenID Connect トークンを使用します。 下記の情報を準備します。

  • 運用する AWS リージョン

  • 先程作成した IAM ロールの ARN

下記は、AWS と認証するために AWS CLI の assume-role-with-web-identity サブコマンド を使ったサンプル設定です。 その後、AWS との簡単なやり取りにより (aws --no-cli-pager sts get-caller-identity)、認証に成功したことを示します。 これを、S3 バケットへのアップロード、ECR へのプッシュ、EKS とのやり取りなど、任意のものに置き換えてください。

version: 2.1

jobs:
  deploy:
    docker:
      - image: amazon/aws-cli
        auth:
          username: mydockerhub-user
          password: $DOCKERHUB_PASSWORD  # context / project UI env-var reference
    environment:
      AWS_DEFAULT_REGION: YOUR_AWS_REGION
      AWS_ROLE_ARN: YOUR_ROLE_ARN
    steps:
      - run:
          name: authenticate-and-interact
          command: |
            # use the OpenID Connect token to obtain AWS credentials
            read -r AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN \<<< \
              $(aws sts assume-role-with-web-identity \
               --role-arn ${AWS_ROLE_ARN} \
               --role-session-name "CircleCI-${CIRCLE_WORKFLOW_ID}-${CIRCLE_JOB}" \
               --web-identity-token $CIRCLE_OIDC_TOKEN \
               --duration-seconds 3600 \
               --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
               --output text)
            export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
            # interact with AWS
            aws --no-cli-pager sts get-caller-identity

高度な設定

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

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

これを行うには、 CircleCI Web アプリ で各プロジェクトのページに行き、Project Settings > Overview に移動し、プロジェクト ID を見つけます。

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

"StringLike": {
  "oidc.circleci.com/org/ORGANIZATION_ID:sub": "org/ORGANIZATION_ID/project/PROJECT_ID/user/*"
}

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

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 UIGrant Access に移動します。ここで求められる設定は、後からダウンロードできます。 CIRCLE_OIDC_TOKEN_FILE という名前のファイルを作成する必要があります。ここから Google Cloud が ID トークンを読み取ります (ファイル名は、credential_source の設定内容と一致していれば任意の名前にできます)。

CircleCI の組織 ID が必要になります。この ID を見つけるには、 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 になります。

    • 発行者は https://oidc.circleci.com/org/ORG_ID で、この ORG_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

次の環境変数を コンテキスト に追加する必要もあります。

コンテキスト変数名

サンプル値

メモ

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 のサポートエンジニアにお問い合わせください。日本語でお問い合わせいただけます。

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