2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CDKでOIDCプロパイダーを作成し、GitHubActionsでOIDCを使用してAWS認証を行う

Last updated at Posted at 2024-08-16

完成物

Pipeline drawio.png

今回の記事ではこれの左側の部分の説明をします。
今後似たような認証機構を構築する時のために備忘録として残しておくための記事です。
間違いや、もっとこうしたら良いなどがあったらコメントしていただけると幸いです。

OIDC認証とは

会社の同期がめっちゃわかりやすい記事を書いてくれていたのでそれを参考しました。

上記の記事より引用。OIDCの流れの簡略化した図
image.png

ものすごくざっくり言うと、
OIDC = 「トークンを使用した短期認証のプロトコル」
と言えそうです

AWS Credentialsのような長期的な認証ではないのでセキュリティ的にも推奨されます。

今回は、
AWS側にOIDCプロバイダーを設置して、GitHubActionsから送られてくるトークンを検証、識別して必要なロールを渡す
という機構を構築していきます。

1. CDKでOIDCプロバイダーと必要なロールをデプロイ

パイプライン用に先にデプロイしていたpipeline-stack.tsにOIDCに関する部分を追加します

最終的にはこのようなコードになります
lib/stacks/pipeline-stack.ts

~~~~

    // 元々定義していたバケットのARNを変数に格納
    const bucketArn = bucket.bucketArn;

    // GitHubのOAuthトークンを取得するためのOpenID Connectプロバイダーを作成
    const idProvider = new iam.OpenIdConnectProvider(this, 'IdProvider', {
      url: 'https://token.actions.githubusercontent.com',
      clientIds: ['sts.amazonaws.com'],
    });

    // GitHub Actionsの特定のワークフローに対してS3への権限を与えるためのロール
    const role = new iam.Role(this, 'Role', {
      roleName: 'GitHubActionRole',
      maxSessionDuration: Duration.hours(1),
      assumedBy: new iam.WebIdentityPrincipal(idProvider.openIdConnectProviderArn, {
        StringLike: {
          'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com',
        },
        StringEquals: {
          'token.actions.githubusercontent.com:sub': 'repo:orgnize/project:ref:refs/heads/main',
        },
      }),
    });

    // 作成したロールにS3への権限を与える
    role.addToPolicy(new iam.PolicyStatement({
      actions: ['s3:PutObject'],
      resources: [bucketArn + '/*'],
    }));

ひとつずつ解説していきます。


AWS側にOIDCプロバイダーを設置する

lib/stacks/pipeline-stack.ts

    // GitHubのOAuthトークンを取得するためのOpenID Connectプロバイダーを作成
    const idProvider = new iam.OpenIdConnectProvider(this, 'IdProvider', {
      url: 'https://token.actions.githubusercontent.com',
      clientIds: ['sts.amazonaws.com'],
    });

この'token.actions.githubusercontent.com'は
GitHub Actions が OIDC トークンを取得する際に内部的に使用するエンドポイント
です。
GitHub Actions のジョブが実行されると、GitHub はこのエンドポイントを介して AWS に送信される OIDC トークンを発行します。
このトークンには、リポジトリ、ブランチ、その他の関連情報が含まれています。

AWS の Security Token Service (STS) をclient(受信者)として定義

image.png

つまり、このようなフローでトークンが届くので、
「発行元がURL通りで受信者がSTSならOKを出すプロバイダー」
を定義したことになります。この段階だとゆるゆるです。

OpenIdConnectProviderの公式APIリファレンスドキュメントはこちら


GitHubActionsで使用するためのロールを定義

lib/stacks/pipeline-stack.ts

    // GitHub Actionsの特定のワークフローに対してS3への権限を与えるためのロール
    const role = new iam.Role(this, 'Role', {
      roleName: 'GitHubActionRole',
      maxSessionDuration: Duration.hours(1), // 有効な時間
      assumedBy: new iam.WebIdentityPrincipal(idProvider.openIdConnectProviderArn, {
        StringLike: {
          'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com',
        },
        StringEquals: {
          'token.actions.githubusercontent.com:sub': 'repo:orgnize/project:ref:refs/heads/main',
        },
      }),
    });

    // 作成したロールにS3への権限を与える
    role.addToPolicy(new iam.PolicyStatement({
      actions: ['s3:PutObject'],
      resources: [bucketArn + '/*'],
    }));

Web Identity (サードパーティをPrincipalとすることができる)にassumeするIAMロールを定義しています。

assumedByの条件でプロバイダーの基本条件に加え、特定のリポジトリやブランチに限定した条件を追加することで、ロールを引き受けることができるトークンをさらに絞り込んでいます。

先ほどと重複しますが、発行されたトークンは、リポジトリ、ブランチ、その他の関連情報が含まれているので、その情報を使用している感じです。

このような流れで、GitHubActionsに対して、同じスタックに定義したS3へPUTする権限を与える準備ができました。

GitHubActionsのワークフローを実装

.github/workflows/infra-deploy.yml

name: infra-deploy

on: #mainへのプッシュをトリガーに起動
  push:
    branches:
      - main

permissions: #ワークフローがリポジトリにアクセス、OIDCトークンを利用しての認証とロールの引き受けを許可
  id-token: write
  contents: read

jobs:
  upload-source:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source
        uses: actions/checkout@v4

      - name: Configure AWS credentials # IAMロールの引き受けと、CLIを実行できるように設定
        uses: aws-actions/configure-aws-credentials@v4 #ここが一番重要
        with:
          aws-region: ${{ secrets.AWS_REGION }}
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }} # 先に定義した'GitHubActionRole'のARNをシークレットに入れておく

      - name: Install AWS CLI
        run: |
          sudo apt-get update
          sudo apt-get install -y awscli

      - name: Zip source code
        run: zip -r source-code.zip .

      - name: Upload source code
        run: aws s3 cp source-code.zip s3://bucket-name-${{ secrets.ENV_NAME }}

uses: aws-actions/configure-aws-credentials@v4
このアクションが、GitHub Actions ジョブが AWS の OIDC プロバイダーとやりとりし、トークンを取得し、そのトークンを使って指定された IAM ロールを引き受けるためのプロセスを担当してます。

GitHubのシークレットの使い方

以上の工程でOIDCを使用した短期認証によってGitHubActionsからS3へのソースコードのプッシュが実装できました

参考にした記事まとめ

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?