永続的なクレデンシャルではなくIAMロールを利用してGithubActionsで認証する

背景

前回、GitHub ActionsでAWS Batchのデプロイを行いました。

AWSの認証では事前にGitHubでSECRETを設定し、GitHub Actionsの中で、ACCESS_KEY_IDSECRET_ACCESS_KEYを設定したSECRETとして利用することで実現していました。

しかし、今は永続的なCredentialsを使うことなく、AWSの認証ができるようです。

https://twitter.com/toricls/status/1438120050167189510

今回は、永続的なCredentialsを用いずにAWSの認証を行ってみようと思います。

IAM Roleの設定

クラスメソッドさんの記事がまとまっていたので、参考にさせていただきました。

GitHub ActionsでAWSの永続的なクレデンシャルを渡すことなくIAM Roleが利用できるようになったようです

ただ、IAM Roleの設定がCloudFormationで書かれていて、CloudFormationに明るくない自分としてはちょっとどうしていいのかわからない状態です。

なので、このCloudFormationの設定をなんとかして、ポチポチで実現しようと思います。

IDプロバイダの追加

まずIDプロバイダの追加を行います。

マネジメントコンソールでIAM -> IDプロバイダを選択します。

  • プロバイダのタイプはOpenID Connectを選択
  • プロバイダのURLにhttps://https://token.actions.githubusercontent.com
  • 対象者にsigstore

と入力し、プロバイダの追加ボタンを押下します。

これでプロバイダの作成は完了です。

IAM Roleの作成

次にロールの作成を行います。

IAM -> IDプロバイダから先程作成したIDプロバイダを選択すると、右上にロールの割り当てというボタンがあるので、押下します。

すると、新しいロールを作成か、既存のロールを使用するを選択できるので、新しいロールを作成を選択します。するとロールの作成画面に遷移します。

ロールの作成画面にて、信頼されたエンティティの種類を選択となっていて、すでにウェブIDが選択されており、IDプロバイダーには先程選択したIDプロバイダーが入力されています。

IDプロバイダ選択

Audienceには、プロバイダーを作成したときに入力したsigstoreが選択できるので、選択して次のステップに移動します。

次はアクセス権限ポリシーをアタッチします。今はテストで行なっていて、この権限の設定で問題が発生すると切り分けが大変なので、一旦強い権限(AdministratorAccess)をアタッチします。

ロールの作成

タグはとばして、ロール名を入力し、ロールの作成ボタンを押下します。

IAM Roleの確認

作成したロールを確認します。

ロールを選択後、信頼関係というタブを押下します。そして、信頼関係の編集というボタンを押下すると、JSON形式で確認できます。

以下のようになっているとOKです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::xxxxxxxxxxxx:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sigstore"
}
}
}
]
}

これでIAM Roleの設定は完了しました。

GitHub Actionsの設定

IAM Roleの準備が整ったので、GitHub Actionsの設定を行います。

基本的には、クラスメソッドさんの記事そのまま実装すれば大丈夫そうです。

以下に実装例を記述します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
name: Deploy to AWS Batch

on:
push:
branches:
- dev

env:
AWS_REGION: ap-northeast-1
AWS_ROLE_ARN: arn:aws:iam::xxxxxxxxxxxx:role/GithubActionsDeployRole
AWS_WEB_IDENTITY_TOKEN_FILE: /tmp/awscreds
ECR_REPOSITORY: test-repository
BATCH_JOB_DEFINITION: aws/batch/job-definition.json
BATCH_JOB_DEFINITION_TEMPLATE: aws/batch/job-definition-template.json

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
permissions:
id-token: write
contents: read

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Configure AWS
run: |
echo AWS_WEB_IDENTITY_TOKEN_FILE=$AWS_WEB_IDENTITY_TOKEN_FILE >> $GITHUB_ENV
echo AWS_ROLE_ARN=$AWS_ROLE_ARN >> $GITHUB_ENV
echo AWS_DEFAULT_REGION=$AWS_REGION >> $GITHUB_ENV
curl --silent -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=sigstore" | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

Login to Amazon ECR以降は永続的なCredentialsを使っている時と同じです。

こちらでActionsを起動して、コンテナイメージのpush、ジョブ定義ファイルのデプロイが完了しました。

ハマったポイント

ハマったポイントとしましては、最初、GitHub Actions内で参照している環境変数ACTIONS_ID_TOKEN_REQUEST_TOKENACTIONS_ID_TOKEN_REQUEST_URLの値が取れておらずなんでだろうと考えていましたが、結果としては

1
2
3
permissions:
id-token: write
contents: read

この設定が漏れていました…

id-tokenに対して、書き込む権限がないと、上記の環境変数は空になってしまうようです。

まとめ

永続的なCredentialsを使うことなくGitHub ActionsにてAWSの認証を行うことができました。

正式な発表はないらしいですが、GitHub Actionsを利用するためだけに専用ユーザーを作成し、永続的なCredentialsを発行してGitHubに設定するという、セキュリティ的に良くないことをしなくてよくなることを考えると、この方法が今後はデファクトになっていくんだろうなと思います。

次回は、先程の環境変数が取得できずに困っていたときに利用した、GitHub ActionsでのSSHデバッグについて記載したいと思います。