🔑

CircleCI が OIDC をサポート! 永続的な AWS Access Key を廃止できる!

2022/03/30に公開

GitHub Actions は以前から OpenID Connect を用いた Cloud Provider への認証が可能でしたが、先日、ついに CircleCI も OIDC をサポートしました 🎉

これにより、AWS で発行する永続的な Access key を廃止することが可能になります!

利用方法

1. CircleCI の Contextを作成する & Organization ID を確認する

1.1 Context の作成

今回のために AWS 用の Context を作成しましょう。
(環境変数の設定は後ほど行います。)

1.2 Organization ID の確認

CircleCI の Organization ID は https://app.circleci.com/Organization Settings > Contexts から取得できます。

(もし、過去一度も Context を作成したことがない場合は、 Organization ID が表示されません。)

Organization ID を控えておく

一度も context を作っていない場合は、 Organization ID が表示されない

2. OIDC identity provider を作成する

  1. IAMコンソール の ナビゲーションパネルにある「ID プロバイダ(Identity providers)」にアクセスします。
  2. 右上にある「プロバイダを追加(Add provider)」をクリックします。
  3. 各入力フォームに以下の情報を入力し、プロバイダを追加します。
値 (<organization-id> には 1. で控えた ID を入力します。)
プロバイダのタイプ (Provider type) OpenID Connect
プロバイダのURL (Provider URL) https://oidc.circleci.com/org/<organization-id>
対象(Audience) <organization-id>

3. CircleCI 上で利用する IAM Role を作成する

(IAM ロールの作成の仕方には細かく言及しません。)

IAM ロールに設定する信頼されたエンティティは「ウェブアイデンティティ(Web Identity)」を選択し、 アイデンティティプロバイダは 「2. OIDC identity provider を作成する」 で作成した ID プロバイダを選択します。

  • 信頼ポリシーは以下のようになります。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AWS account id>:oidc-provider/oidc.circleci.com/org/<organization-id>"
            },
            "Action": "sts:AssumeRoleWithWebIdentity"
        }
    ]
}

作成した Role の ARN は、後で使うので控えておくと良いでしょう。

4. 1.1 で作った Context に環境変数をセットする

Name Value
AWS_REGION <お使いのリージョン> ( 例: ap-northeast-1 )
AWS_IAM_ROLE_ARN arn:aws:iam::<account_id>:role/<role_name>

5. .circleci/config.yml を作成する

以下のように記述することで、 AWS の認証を行うことができ、 aws sts get-caller-identity で AWS の Account ID などが取得することができます。

l060ki/aws-configure-with-oidc@0.1.1 というを利用していますが、これは筆者が即席で作ったものです。 circleci/aws-cli orb でサポートされるかもしれないですが、サポートされるまでの暫定対応として、雑な orb を作りました。(ドキュメントなどは全く書いておらず、恐縮ですが。)
※ ご利用は自己責任でお願いします。

version: 2.1

orbs:
  aws-cli: circleci/aws-cli@2.1.0
  aws-configure-with-oidc: l060ki/aws-configure-with-oidc@0.1.1

jobs:
  build:
    docker:
      - image: cimg/python:3.10
    environment:
      AWS_REGION: ap-northeast-1
    steps:
      - aws-configure-with-oidc/assume-role:
          role-arn: AWS_IAM_ROLE_ARN # context に設定した IAM Role の ENV の名前
      - run:
          name:
          command: |
            aws sts get-caller-identity

workflows:
  build-and-test:
    jobs:
      - build:
          context:
            - aws-oidc-deploy

▼ 実行結果

おまけ

特定の Project (Repository) にだけ Assume Role を許したい場合

Circle CI の OIDC token の仕様 を参照すると、 sub に project-id が含まれていることがわかります。これを使って、特定の Project にだけ、 Assume Role を可能にしたい場合は、以下のように信頼ポリシーを修正することで、実現できます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AWS account id>:oidc-provider/oidc.circleci.com/org/<organization-id>"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "oidc.circleci.com/org/<organization-id>:sub": [
                        "org/<organization-id>/project/<project-id>/*"
                    ]
                }
            }
        }
    ]
}

さいごに

CircleCI が OIDC をサポートしたことで、 AWS IAM User の Access Key を廃止することが可能となり、これで、キーローテーションなどを行う必要がなくなりました。

(追記) Terraform でリソースを作成する方法も書きました!
AWS ↔ CircleCI OIDC 連携を Terraform で実現する

Discussion