GitHub ActionsとAWSのOIDC連携で特定のRepositoryやBranchにのみAssumeRoleを許可させてみた
こんにちは、CX 事業本部 IoT 事業部の若槻です。
今回は、GitHub Actions と AWS の OIDC 連携で特定の Repository や Branch にのみ AssumeRole を許可させてみました。
設定箇所
GitHub と AWS の OIDC 連携をさせるためには、AWS には次の 2 つのリソースを作成する必要があります。
- ID Provider
- IAM Role(および Inline Policy)
そして OIDC 可能な GitHub の Repository や Branch を制限する場合は、IAM Role の Trusted entities のConditionを設定する必要があります。
{ "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:sub": "repo:<Account>/<Repository>:ref:refs/heads/<Branch>" } } } ] }
IAM Role の Trusted entities は、マネジメントコンソールで上だと[Trust relationships]の[Trusted entities]で確認および設定できます。
AWS CDK で作成するならaws_iam.FederatedPrincipal
の第二引数が Condition に該当する部分です。(詳細は以前のエントリを参照)
const oidcDeployRole = new aws_iam.Role(this, 'GitHubOidcRole', { roleName: 'github-oidc-role', assumedBy: new aws_iam.FederatedPrincipal( gitHubIdProvider.openIdConnectProviderArn, { StringLike: { 'token.actions.githubusercontent.com:sub': props.principalFederatedSub, }, }, 'sts:AssumeRoleWithWebIdentity' ), });
やってみた
次の Workflow で試してみます。Secret から取得した IAM Role の Arn をaws-actions/configure-aws-credentialsで使用して OIDC による AssumeRole を行っていまうす。
on: push: paths-ignore: - '**/*.md' jobs: assumerole: runs-on: ubuntu-latest env: AWS_OIDC_ROLE_ARN: ${{ secrets.AWS_OIDC_ROLE_ARN }} AWS_REGION: ap-northeast-1 permissions: id-token: write contents: read steps: - name: debug run: | echo AWS_OIDC_ROLE_ARN: ${AWS_OIDC_ROLE_ARN/::*:/::XXXXXXXXXXXX:} - name: Assume Role uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{ env.AWS_OIDC_ROLE_ARN }} aws-region: ${{env.AWS_REGION}}
Repository 名がaws-cdk-
から始まり、Branch 名がfeature/
から始まるという Condition で試してみます。StringLike
Operator によりこのようなワイルドカード(*
)の使用が可能となります。
{ "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:cm-rwakatsuki/aws-cdk-*:ref:refs/heads/feature/*" } } } ] }
使用できる Condition operator については下記をご参照ください。
パターン1
- Repository
aws-cdk-v2-project
(一致) - Branch
feature/hoge1
に Commit を Push(一致)
Workflow の実行が成功しました。
パターン2
- Repository
aws-cdk-v2-project
(一致) feature/hoge1
からdevelop
に Branch を Merge(一致?)
AssumeRole がNot authorized to perform sts:AssumeRoleWithWebIdentity
となり Workflow の実行が失敗しました。Merge 時は Compare Branch ではなく、Base Branch が Condition で許可されている必要があるようです。
パターン3
- Repository
aws-cdk-v2-project
(一致) - Branch
aaaaaaaaaa
に Commit を Push(不一致)
Branchaaaaaaaaaa
に Commit を Push すると、AssumeRole がNot authorized to perform sts:AssumeRoleWithWebIdentity
となり Workflow の実行が失敗しました。
パターン4
- Repository
aws_cdk_app
(不一致) - Branch
feature/hoge1
に Commit を Push(一致)
AssumeRole がNot authorized to perform sts:AssumeRoleWithWebIdentity
となり Workflow の実行が失敗しました。
補足
StringEqualsで指定する場合
Condition でワイルドカードを使わずに、StringEquals
Operator で複数の値を指定することもできます。
"Condition": { "StringEquals": { "token.actions.githubusercontent.com:sub": [ "repo:cm-rwakatsuki/aws-cdk-v2-project:ref:refs/heads/feature/hoge1", "repo:cm-rwakatsuki/aws-cdk-v2-project:ref:refs/heads/develop", ] } }
おわりに
GitHub Actions と AWS の OIDC 連携で特定の Repository や Branch にのみ AssumeRole を許可させてみました。
IAM Role 側で今回のような制限を行うことにより、Role が不本意な Repository で使われてしまったり、不必要な AWS アカウントへの AssumeRole が可能となってしまったりするリスクを権限することができます。OIDC 連携をする際には要確認しておきたいですね。
以上