セキュリティ強化を目指して、なるべく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プロバイダの追加を行います。
- プロバイダのタイプ:OpenID Connect
- プロバイダのURL:
https://token.actions.githubusercontent.com
- 対象者:
sts.amazonaws.com
GitHubのOIDCプロバイダ(token.actions.githubusercontent.com)のサムプリントを取得し、AWSのOIDC IDプロバイダ設定に追加することで、GitHub ActionsがAWSサービスに安全にアクセスできるようになります。
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
以下が改修点となります。
-
permissions
の追加: 改修後のワークフローには、新たにpermissions
セクションが追加されています。これはGitHub ActionsがOIDCトークンを要求し、利用するために必要な設定です。id-token: write
はGitHubからOIDCトークンを取得するための権限を与え、contents: read
はリポジトリの内容を読むための権限を設定しています。 -
クレデンシャルの除去: 改修前のワークフローでは、
aws-access-key-id
とaws-secret-access-key
を使用してAWSに認証していましたが、改修後のワークフローではこれらが削除されています。これにより、IAMユーザーのクレデンシャルを公開するリスクがなくなり、セキュリティが向上します。 -
configure-aws-credentials
アクションの変更:aws-actions/configure-aws-credentials
アクションの使用方法が変更されており、OIDCトークンを用いてAWSに認証するように変更されています。role-to-assume
は引き続き使用されており、OIDCにより承認されたGitHub Actionsワークフローが指定されたIAMロールを引き受けることを可能にします。