こんにちは、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を設定する必要があります。
Trusted entities
{
"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に該当する部分です。(詳細は以前のエントリを参照)
lib/aws-cdk-v2-project-stack.ts
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を行っていまうす。
.github/workflows/cicd.yaml
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によりこのようなワイルドカード(*
)の使用が可能となります。
Trusted entities
{
"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で複数の値を指定することもできます。
Trusted entities(抜粋)
}
}
おわりに
GitHub ActionsとAWSのOIDC連携で特定のRepositoryやBranchにのみAssumeRoleを許可させてみました。
IAM Role側で今回のような制限を行うことにより、Roleが不本意なRepositoryで使われてしまったり、不必要なAWSアカウントへのAssumeRoleが可能となってしまったりするリスクを権限することができます。OIDC連携をする際には要確認しておきたいですね。
以上