見出し画像

OpenID ConnectならGitHub Actionsでクレデンシャルを使わずにデプロイできる

こんにちは、すずきです。

セキュリティ強化を目指して、なるべくIAMユーザーの使用を最小限に抑えて、IAMロールで一時的な権限付与を行う手法を取り入れてきました。

ただ、GitHub Actionsのデプロイワークフローにおいては、AssumeRoleする際にIAMユーザーのクレデンシャル(アクセスキーとシークレットアクセスキー)が必要だと思っていて、以前その方法を採用しました。

しかし、よく調べてみたら、OpenID Connectを使うと、クレデンシャルを使わずにワークフロー内でAssumeRoleできることがわかり、ワークフローを改善しました。

DevOps経験のあるエンジニアには既知の内容だと思いますが、初心者の方々への参考として、改善内容を共有します。


OpenID Connectとは

OpenID Connect(OIDC)は、ユーザー認証を行うためのオープンスタンダードプロトコルです。OAuth 2.0プロトコルを基にしていて、安全な方法でユーザーの身元情報を確認することができます。

OIDCを使うと、GitHub ActionsのワークフローがGitHub(OpenID Connectプロバイダとして)から特定のワークフローに関連する情報(リポジトリ名、ワークフローIDなど)を含む一時的なトークンを要求します。GitHubはこの要求に応じてトークンを生成し、これがワークフローの実行中のみ有効となります。そのため、IAMユーザーのアクセスキーを用いる方法に比べて、セキュリティが向上し、管理が容易になります。

生成されたOIDCトークンは、GitHub ActionsワークフローからAWSに送信されます。AWS上では、あらかじめ設定されたIAMロールがOIDCプロバイダ(GitHub)からのトークンを受け入れるように設定されています。このIAMロールは特定のポリシー(権限のセット)と関連付けられていて、OIDCトークンに基づいて、GitHub Actionsワークフローに特定のAWSリソースへのアクセスを許可します。

GitHub Actionsワークフローは、AWSの「AssumeRoleWithWebIdentity」APIを呼び出して、提供されたOIDCトークンを使用して、指定されたIAMロールのアクセス許可を取得します。このステップで、AWSはOIDCトークンを検証し、トークン内の情報が設定されたIAMロールと一致する場合にのみアクセスを許可します。

簡単に言うと、OIDCを使うことで、GitHub Actionsは「一時的な証明書」を受け取り、それを使って必要な操作を行うことができるようになります。これによって、IAMユーザーのクレデンシャルをワークフロー内に保持する必要がなくなり、セキュリティリスクが大幅に軽減されます。

実装

順番に説明します。

IDプロバイダの追加(AWS)

IDプロバイダを設定することで、GitHub Actionsからのリクエストが正当であることをAWS側が確認できます。OIDC IDプロバイダの設定によって、GitHub Actionsのワークフローから生成された認証トークンが検証され、そのトークンに基づいて特定のAWSリソースへのアクセスが許可されます。

AWSのマネジメントコンソールの「IAM > IDプロバイダ > IDプロバイダを作成」から以下の設定でIDプロバイダの追加を行います。

GitHubのOIDCプロバイダ(token.actions.githubusercontent.com)のサムプリントを取得し、AWSのOIDC IDプロバイダ設定に追加することで、GitHub ActionsがAWSサービスに安全にアクセスできるようになります。

IDプロバイダの追加

IAMロールの作成

AssumeRoleするIAMロールを作成します。
デプロイに必要なIAMポリシー(ECSへのデプロイだったらECSやECRへのアクセス権限など)を付与し、信頼関係タブで以下のJSONを用いて信頼されたエンティティを設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<account-id>:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
                    "token.actions.githubusercontent.com:sub": "repo:<organization-name>/<repository-name>:*"
                }
            }
        }
    ]
}

こちらのJSONでは、GitHub Actionsからの認証リクエストを許可するための条件を定義します。

  • Principal: GitHub ActionsのOIDCプロバイダ(token.actions.githubusercontent.com)を指定します。

  • Action: sts:AssumeRoleWithWebIdentityは、Webアイデンティティ(OIDCトークン)を使用してIAMロールを引き受けるアクションを指します。

  • Condition: 特定のGitHubリポジトリ(<organization-name>/<repository-name>)からのリクエストを指定します。

このIAMロールと信頼関係の設定によって、GitHub Actionsの特定のワークフローが、AWS上で指定されたサービスにアクセスするための権限を持つようになります。

デプロイワークフローの改修

ワークフローを以下のように改修します。

改修前

name: Lambda Deploy
on:
  push:
    branches:
      - develop
    paths:
      - "**"
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: install dependencies
        run: yarn install
        working-directory: ./

      - name: configure aws
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_TO_ASSUME }}
          role-duration-seconds: 3600


改修後

name: Lambda Deploy
on:
  push:
    branches:
      - develop
    paths:
      - "**"
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: install dependencies
        run: yarn install
        working-directory: ./

      - name: configure aws
        uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_TO_ASSUME }}
          aws-region: ${{ secrets.AWS_REGION }}
          role-session-name: GitHubActions
          role-duration-seconds: 3600

以下が改修点となります。

  1. permissionsの追加: 改修後のワークフローには、新たにpermissionsセクションが追加されています。これはGitHub ActionsがOIDCトークンを要求し、利用するために必要な設定です。id-token: writeはGitHubからOIDCトークンを取得するための権限を与え、contents: readはリポジトリの内容を読むための権限を設定しています。

  2. クレデンシャルの除去: 改修前のワークフローでは、aws-access-key-idとaws-secret-access-keyを使用してAWSに認証していましたが、改修後のワークフローではこれらが削除されています。これにより、IAMユーザーのクレデンシャルを公開するリスクがなくなり、セキュリティが向上します。

  3. configure-aws-credentialsアクションの変更: aws-actions/configure-aws-credentialsアクションの使用方法が変更されており、OIDCトークンを用いてAWSに認証するように変更されています。role-to-assumeは引き続き使用されており、OIDCにより承認されたGitHub Actionsワークフローが指定されたIAMロールを引き受けることを可能にします。


いいなと思ったら応援しよう!