電通総研 テックブログ

電通総研が運営する技術ブログ

OpenID Connectを利用してGitHub ActionsからAWSリソースにアクセスする

皆さん、こんにちは。電通国際情報サービス(以下、ISID)Xイノベーション本部アドバンストテクノロジー部の宮原です。 本日よりISIDのテックブログが開始されます。そして、本記事はISIDテックブログの記念すべき第一号です。

また、12月からはAdvent Calendarを実施していく予定です。Advent Calendarのリンクは以下にあります。

https://adventar.org/calendars/6576

こちらもぜひ楽しみにしていてください。

さて、第一号の本記事ではGitHub Actionsの新機能についてご紹介します。 10/27にGitHub Blogにて以下のアナウンスがありました。

https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/

ブログのタイトルはGitHub Actions: Secure cloud deployments with OpenID Connectとなっています。このアナウンスによって、OpenID Connectを利用しGitHub Actionsからクラウドリソースにアクセスできるようになりました。

本記事ではOpenID Connectを利用し、GitHub ActionsからAWSリソースへアクセスする方法についてご紹介します。 以下ではOpenID ConnectをOIDCと略します。

概要

OIDCを利用したクラウドリソースへのアクセスについては以下のドキュメントを参考にすると良いでしょう。

https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect

以下は公式ドキュメントの画像です。

  1. クラウドプロバイダーにてロールとGitHub Actionsジョブ間のOIDCの信頼関係を設定する。
  2. GitHub Actionsのジョブが実行されるたび、GitHubのOIDCプロバイダーはOIDCトークンを自動生成する。
  3. GitHubのOIDCプロバイダーからOIDCトークンを取得し、クラウドプロバイダーに送信する。
  4. クラウドプロバイダーはOIDCトークンの検証に成功したら、ジョブ内でのみ有効な、一時的な認証トークンを提供する。

このような流れで一時的な認証トークンを入手し、さらに認証トークンを用いてクラウドリソースにアクセスします。

上記の流れを実現するために、AWSでは、Web IDフェデレーションの機能を利用します。Web IDフェデレーションを利用し、最終的にはIAMロールをマッピングした一時的な認証トークンを提供します。

方法

ここからは、OIDCを利用しGitHub ActionsからAWSリソースへアクセスする方法について記述します。 今回は、S3へのファイルアップロードを行うGitHub Actionsジョブを作成します。 AWSの各設定は全てGUIから行いました。

IAM OIDC ID プロバイダーを作成する

まずは、AWS上でOIDC IDプロバイダーを作成します。これはGitHub OIDCプロバイダーの情報をAWSに登録する作業です。 AWSコンソールのIAM、IDプロバイダーの作成からIDプロバイダーを作成します。

OIDC IDプロバイダーの設定情報は以下のドキュメントに載っています。

https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

ドキュメントに則り、OIDC IDプロバイダーの設定情報として以下を入力しました。

プロバイダーのURL: https://token.actions.githubusercontent.com

対象者: sts.amazonaws.com

aws-actions/configure-aws-credentials を利用する場合は対象者の項目にsts.amazonaws.comを入力します。

IAM ロールを作成する

次にIAM ロールを作成します。コンソールからIAM、ロール、ロールを作成を選択し、ロールを作成します。

今回はWeb ID フェデレーションの機能を利用するため、信頼されたエンティティの種類にウェブIDを選択します。 IDプロバイダー、Audienceには先ほど作成した、IDプロバイダーの情報を入力します。

アクセス権限はGitHubActionsで実施したい作業に応じて設定します。

今回はS3へのファイルアップロードを実施するため、特定のバケットへのPutObjectを許可するポリシーを持つ、IAMロールを作成しました。

IAMロールを作成した後に信頼関係の修正を行います。特定のGitHubリポジトリからのみのアクセスに制限する設定を追加します。この作業は必ず実施してください。 制限を追加しないと、全てのリポジトリGitHub Actions上からIAMを利用できてしまいます。

信頼関係を修正するために、作成したIAMロールを選択し、信頼関係のタブから信頼関係の編集を選択します。

エディターが開かれるので、項目を追加します。今回はStatement.Conditionの項目に以下の条件を追加します。 これによって特定のリポジトリからのみ、IAMを利用できます。*の部分を詳細に記述し、ブランチの制限を加えることも可能です。

"StringLike": {
  "token.actions.githubusercontent.com:sub": "repo:<リポジトリの所有者>/<リポジトリ名>:*"
}

最終的な信頼関係のポリシーは以下になります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<AWSのアカウントID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:<リポジトリの所有者>/<リポジトリ名>:*"
        }
      }
    }
  ]
}

aws-actions/configure-aws-credentialsにIAMロール作成のCloudFormation Templateがあります。こちらを利用してIAMロールを作成するのも良いでしょう。

GitHub Actionsから一時的な認証情報を取得する

最後にGitHub Actionsの設定です。GitHub ActionsのYAMLファイルを記述します。今回は以下のYAMLファイルを作成しました。

name: Upload File
on:
  push
jobs:
  upload:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v2
      - uses: aws-actions/configure-aws-credentials@master
        with:
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
          role-session-name: github-actions-sample-session
          aws-region: ap-northeast-1
      - run: aws s3 cp ./test.txt s3://${{ secrets.AWS_S3_BUCKET_NAME }}/

GitHub Actionsのジョブ内でOIDCトークンを取得するにはpermissionsのid-tokenの権限をwriteにする必要があります。

IAMロールのARNはリテラルで書くこともできますが、できる限りGitHub ActionsのSecretに記述したほうが良いでしょう。 IAMロールのARNが漏えいし、先程の信頼関係が適切に設定されていないと、不正利用されてしまいます。

また、利用する aws-actions/configure-aws-credentialsのバージョンをv1ではなく、masterにしています。v1のリリースにはOIDCの機能が含まれていないため、masterブランチを指定しないと動作しません。こちらも注意するポイントです。

この設定で、特定のS3バケットへのファイルアップロードが可能になりました。

まとめ

本記事ではGitHub ActionsのOIDC機能を利用し、GitHub ActionsからAWSリソースへアクセスする方法について記述しました。OIDCを利用することによって、アクセスキーを利用せずAWSリソースにアクセスできるようになりました。

これによってアクセスキーの漏えいのリスクを軽減できます。しかしながら、IAMロールの信頼関係を適切に設定しないと、別の不正利用にも繋がります。慎重に設定しましょう。

最後までお読みいただきありがとうございました。ISID Advent Calendarも楽しみにしていください。

参考にした情報

執筆:@miyahara.hikaru、レビュー:@sato.taichiShodoで執筆されました