この記事は、マイナビ Advent Calendar 2021 4日目の記事です。
概要
本記事は、2021年11月1日にGitHubから発表された、GitHub ActionsによるOpenID Connectの概要や実装方法等をまとめた記事になります。
GihHub ActionsでAWSの永続的なクレデンシャル(IDやパスワードをはじめとする、ユーザ等の認証に用いられる情報の総称)を渡すことなく、IAM Roleが利用できるようになったので、その紹介です。
前提知識
- GitHub Actions
- GitHubのCI/CDツール。この記事では、ワークフロー(リポジトリに追加する自動化された手順。 スケジュールまたはイベントによって動く。 ワークフローを使用して、GitHubでプロジェクトをビルド、テスト、パッケージ、リリース、またはデプロイできる。)が分かっていれば読み進められると思います。
- 詳しい内容はこちらの記事を参考にしてください。
- OAuth
- 権限譲渡のプロトコル。OAuthによって、ユーザのアクセス権限を様々なアプリに渡すことが出来る。その際は、アクセストークンを発行することでアクセス権限を移譲するため、IDやパスワードなどの情報をアプリ側に渡さずに済む。
- 詳しい内容はこちらの記事を参考にしてください。
- OIDC(OpenID Connect)
- OAuthを基にして作られた、より安全に認証することが出来る技術。アクセス権を移譲する際に、アクセストークンと同じタイミングでIDトークンも発行する。
- 詳しい内容はこちらの記事を参考にしてください。
はじめに
今年の9月頃、以下のツイートが話題になりました。
Ok I blogged about it. That's how excited I am.
— Aidan W Steele (@__steele) September 15, 2021
1. Deploy this CFN template
2. Write this GHA workflow
3. Never worry about IAM users again
https://t.co/KJrr2Jw4bE pic.twitter.com/9IcocgurxP
その後11月に正式にリリースされました。
これにより、GitHub ActionsからAWSを利用するときに必要だった、GitHub Actions実行用のアクセスキーが不要になります。
理由は、IAMでIDプロバイダを作り、GitHub側のOIDCで許可することにより、GitHub側からの権限の呼び出しを行えるからです。
詳しい設定内容等は実装を確認してください。
Github ActionsによるOIDC
Github ActionsによるOIDCは上記のダイアグラムのようになっています(ダイアグラム参照記事)。
① AWSにアクセスするリソースやIAM Roleなどがこれにあたります。
② GitHub Actionsのワークフローが実行されるたびに、GitHub Actionsの環境変数から、OIDCプロバイダーがIDトークンを自動生成します。
③ GitHubのOIDCプロバイダーが自動生成したトークンを基に、AWSリソースへのアクセスをリクエストします。
④ ③のリクエストが問題ない場合、短期間だけ利用できるクラウドアクセストークンをGithub側に返すことで、Github ActionsからAWSリソースへアクセスすることが出来ます。
詳しくはこちらをご覧ください(英語)。
実装
ワークフローを実装するにあたり、
- リポジトリを作成し
- 利用するIAMロールを作り
- ワークフローを作成する
という順番で進めていきます。
1. リポジトリの作成
2. IAM Roleの作成
Github Actionsで使用する、IAM Roleと認証連携のためのIDプロバイダを作成します。
2.1 IDプロバイダの作成
- IAM>IDプロバイダに画面遷移する
- 「プロバイダを追加」を押下する
- プロバイダのタイプを「OpenID Connect」にする
- プロバイダのURLに
https://token.actions.githubusercontent.com
と入力し、「サムプリントを取得」を押下する - 対象者には、
sts.amazonaws.com
と入力する - 右下の「プロバイダを追加」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422940/796777b0-c9e8-2c37-40cd-7c32f3408c02.png)
2.2 IAM Roleの作成
- IAM>ロールに画面遷移する
- 「ロールを作成」を押下する
- 「信頼されたエンティティの種類を選択」で「ウェブID」を選択する
- 「IDプロバイダー」のプルダウンで、上記で設定したIDプロバイダを選択する
- 「Audience」で、上記で設定した「sts.amazonaws.com」を選択する
- 「次のステップ:アクセス権限」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422940/4e52d0f9-1835-c7d0-53ca-53b7c06e861a.png) 7. 「Attachアクセス権限ポリシー」「タグの追加」は特に変更せず次のステップに進む 8. 「確認」画面で任意の名前を入力し、「ロールの作成」を押下する ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422940/dd383d6d-6675-1d2a-58b5-d678ac753052.png)
特定アカウントやリポジトリに対する設定はこちらを確認してください。
3. ワークフローの作成
今回私は、GithubのGUIでファイルを作成したので、その方法を記載します。
すでにあるリポジトリ内にワークフローを作成する場合は、リポジトリの.github/workflow
配下に、yml形式のファイルを作成してください。そのファイルに、下記で記載するoidc_test.yml
のコードを入力して下さい。その後pushすることで、Github Actionsが走ります。
- 1.で作成したリポジトリの画面で「Actions」画面に遷移する
- 「Set up this workflow」を押下する
- ファイル名を任意で入力し、ファイル内に以下のコードを記載する
- 「Start commit」を押下して、
create oidc_test.yml
などのコミットメッセージを入力し、「Commit new file」を押下する。
name: OIDC test
on:
push:
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- run: sleep 5
- name: Configure AWS
run: |
export AWS_ROLE_ARN=arn:aws:iam::XXXXXXXXXXXX:role/github-actions-oidc-test
export AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/awscreds
export AWS_DEFAULT_REGION=ap-northeast-1
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_DEFAULT_REGION >> $GITHUB_ENV
curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE
- run: aws sts get-caller-identity
ポイントはpermissions: id-token: write
の部分です。これを指定することで、IDトークンの取得に必要な情報が環境変数に設定されます。
run: sleep 5
の部分は合っても無くても大丈夫です。
Configure AWS: run
の部分では、IAMロール・トークンファイルパス・リージョンを、Github Actionsの環境変数にセットし、Githubに対してトークンリクエストを投げています。
awscliでは、AWS_ROLE_ARN
に作成したIAMロールのarnを、AWS_WEB_IDENTITY_TOKEN_FILE
にトークンファイルのファイルパスをセットしておくことで、トークンファイルを読み込み、設定したIAMロールをAssumeRoleWithWebIdentity
で呼び出して使用してくれます(AWS CLIのドキュメント)。
最後のcurl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com"
で、Githubに対してトークンを発行するためのリクエストを投げています。
参考にした記事では、GitHub Actionsが持っている$ACTIONS_ID_TOKEN_REQUEST_TOKEN
の値を使って$ACTIONS_ID_TOKEN_REQUEST_URL
にリクエストを送り、一時トークンを発行しているというようなことが記載されていました。
4. 動作確認
それでは実際にGithub Actionsを実行してみます。
「Actions」>「OIDC test(ymlファイルに設定したワークフロー名)」>「create oidc_test.yml(コミットメッセージ)」>「build」と遷移すると以下の画面に行きつくと思います。
もし記事の通り実装した場合、ファイルを編集してコミットしたので、すでにワークフローが実行されている状態になります。
緑色のチェックマークが表示されていれば成功です。
マスクしていますが、UserId、Account、Arnに正しい情報が表示されていました。
補足
configure-aws-credentialsライブラリの利用
本記事のワークフローの作成では、一通りの処理の流れを追うために、run
にコマンドを直書きして実装しました。
現在はコマンド直書きで利用するよりも、aws-actions/configure-aws-credentials
ライブラリを利用したほうがスッキリするのでその方法も紹介したいと思います。
IDプロバイダやロールは実装で作成したままの設定で問題ありません。
name: AWS Deploy
on: push
env:
AWS_ROLE_ARN: arn:aws:iam::XXXXXXXXXXXX:role/github-actions-oidc-test
permissions:
id-token: write
contents: read
jobs:
aws-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: aws-actions/configure-aws-credentials@master
with:
role-to-assume: ${{ env.AWS_ROLE_ARN }}
aws-region: ap-northeast-1
- run: aws sts get-caller-identity
この方法では、env
にロールのarnを設定し、permissions.id-token
を同じくwrite
にすることで、同じようにAssumeRoleし、AWSリソースにアクセスできます。
成功しました。
特定のアカウントやリポジトリに対するロールの設定
IDプロバイダの作成で、対象者にsts.amazonaws.com
を対象者として設定しました。
この場合、AWSアカウントIDとIAMロール名の二つが分かっている人であれば、誰でもAssumeRoleが可能になってしまいます。
IAM Roleを以下のように設定することで、指定したOrganization、もしくはAccount配下のリポジトリのみで該当ロールを使用することが出来ます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::XXXXXXXXXXXX:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:${Organization名 or Account名}/*"
}
}
}
]
}
さらにrepo:${Organization名 or Account名}/${リポジトリ名}:*
と指定すれば、指定したリポジトリ内でしか使用できません(*
はブランチ名を指定できます)。指定したリポジトリのGithub Actionsで発行したトークンだけが、ロールを引き受けるようにしているため、安全に使用できます。
まとめ
この機能によって、Github ActionsからセキュアにAWSにアクセスできるようになりました。
OIDCはGithub Actionsに実装された機能なのでGCPでも利用できるようです。
参考になれば幸いです。
参照
https://dev.classmethod.jp/articles/github-actions-without-permanent-credential/
https://zenn.dev/yutaro1985/articles/b012f69b49bec095b9f1
https://zenn.dev/mryhryki/articles/2021-09-19-access-aws-by-github-actions
https://tech.guitarrapc.com/entry/2021/11/05/025150