こんにちは、サーバーサイドエンジニアのいわむ(@k_iwamu)です。
GitHub Actions で 各クラウドとOIDC経由で認証認可をする機能がGeneral Availability(以下 GA)となりました。
弊社でもGA前からエンジニア達で注目していた機能でありました。
そしてタイミングよく新しくGitHubのリポジトリを作って開発する機会があったため、早速 AWSのID プロバイダーと連携してCI/CDのフローを作ってみました。
何が嬉しいのか
永続的なkeyの発行が不要になりセキュリティの懸念が軽減されたことです。
(弊社では主にAWSを利用しているのでその前提で話をしますが)
もともとCI/CDのサービス(GitHub ActionsやCircleCI)に永続的なIAM Userのkeyを保持し、そのUserの権限を元にAWSのAPIを利用していました。
Userの権限を最小限にすることはできるものの、そのためにGitHubのリポジトリごとにIAM Userを生成していくつものkeyを管理する必要が出てきたり、また権限に永続性があるため、keyが流出した時点でセキュリティ問題につながる懸念がありました。
それがAPIを利用するたびにOIDCのフローによって認証認可が行われ、期限があるkeyが都度払い出されるようになったため、セキュリティによる懸念が軽減されました。
手順
ID プロバイダーの作成
こちらは固定値を設定するだけなので簡単に作成することができます。
- 対象者(client id list):
sts.amazonaws.com
(GA前のバージョンだと違う値を入れる仕様だったため注意が必要です。) - プロバイダーのURL:
https://token.actions.githubusercontent.com
- サムプリント:
a031c46782e6e6c662c2c87c76da9aa62ccabd8e
(コンソールで作成する場合は「サムプリントを取得」ボタンで値を取得してくれます。)
IAM Roleの作成
OIDC 経由で GitHub からリクエストされたときにAssume して利用するためのRoleです。
そのためRoleにはCI/CDのために必要な権限を与えればよいです。
また、信頼ポリシーでは、OIDCでリクエストされたときにRoleをAssumeするための設定を加えます。
{ "Version": "2008-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:sub": "repo:<organization_name>/<repository_name>:*" } } } ] }
account_id: AWSのアカウントID
organization_name: GitHubのorganization名
repository_name: GitHubのrepository名
GitHub Actions
こちらはサンプルコードになります。
記述はシンプルです。
name: <name> on: [push] jobs: auth: name: auth runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-region: ap-northeast-1 role-to-assume: <iam_role_arn> role-session-name: <repository_name>-github // CloudTrail イベントにユーザー名が出るので識別できる名前をおすすめします - name: Get Caller Identify // 権限が与えられていることを確認するためなので、このフローはなくても問題ないです run: aws sts get-caller-identity
iam_role_arn: 作成したRoleのArn
Get Caller Identifyのフロー時に権限が渡されていることを確認できます 🎉 🎉
{ "UserId": "<iam_role_id>:<role-session-name>", "Account": "***", "Arn": "arn:aws:sts::***:assumed-role/<role_name>/<role-session-name>" }
最後に
弊社は基本的にCircleCIを使っていますが、
セキュリティ面でのメリットに加え、CI/CDをGitHubとAWS間で完結できるメリットもあるため、GitHub Actionsに移行する声もあがっています。
ぜひみなさまもご検討ください。
PR
子育て家族アプリFammを運営するTimers inc.では現在エンジニアを積極採用中! オンラインでの面談やカジュアルランチなどもやってますので是非お気軽にご連絡ください!