はじめに
勇気を出して、以下イベントのCfPを出したら、なんとLTさせて頂くことになりました!
そこでしばらく、登壇資料を作成するための検証記事を書いていきます。
確認すること
今回はAWSの最小権限の設定をどうやったら楽に設定できるか?を調べてみる。という内容です。
そのうち、今回はIAM Access Analyzer Policy Generationを使ったケースでの検証です。
検証
今回は、Github ActionsからAWS SAMをデプロイするときの最小権限を考えてみます。
GitHub ActionsがOIDC経由でAWSから委任されるロールを対象に検証してみました。
仕組みは以下に記事を書いているので、参考にしてみてください。
手順は以下です。
- 強い権限でリソース操作
- IAM Access Analyzer Policy Generationを使ってポリシー生成
- 動作確認
なお、ワークフローは以下のような感じです。
name: Deploy-AWS-SAM-Application
on:
push:
branches:
- 'main'
env:
SAM_CLI_TELEMETRY: 0
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-22.04
environment: main
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- uses: aws-actions/setup-sam@v2
with:
use-installer: true
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: ap-northeast-1
role-session-name: SamDeploy
- run: sam build
- run: sam deploy --stack-name ${{ vars.STACK_NAME }} --resolve-s3 --capabilities CAPABILITY_IAM --no-confirm-changeset --no-fail-on-empty-changeset
(事前準備)CloudTrail証跡の作成
事前にCloudTrailの証跡を作成しておきます。
特にデータイベントの管理などはせず、デフォルト設定です。
1.強い権限でリソース操作
まずは、一時的にAdministratorAccessなどの強い権限を付与したのロールで、Stackの作成や更新操作を行、証跡を記録させておきます。
念の為、デプロイが成功したことを確認しておきます。
2. IAM Access Analyzer Policy Generationを使ってポリシー生成
一通り証跡が記録されたはずなので、ロールの作成をしてみます。
Github Actionsに委任したロールを表示し、CloudTraiイベントに基づいてポリシーを生成からポリシーを生成を選択します。
期間は一番短い1日に設定し、事前に準備した証跡やリージョンの指定などを行い、ポリシーを生成を実行します。
これで作成が開始されました。
しばらく待ってリロードしてみると、ステータスが成功になるので、生成されたポリシーを表示からポリシー生成に進みます。
CloudFormation,Lambda,STSのアクションが記録されていました。
一部ポリシーが不足している気もしますが、一旦そのまま進みます。
作成された許可ポリシーは以下。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudformation:DescribeStacks",
"cloudformation:ListStacks",
"sts:GetCallerIdentity"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cloudformation:CreateChangeSet",
"cloudformation:DescribeChangeSet",
"cloudformation:DescribeStackEvents",
"cloudformation:ExecuteChangeSet"
],
"Resource": "arn:aws:cloudformation:${Region}:${Account}:stack/${StackName}/${Id}"
},
{
"Effect": "Allow",
"Action": [
"lambda:AddPermission",
"lambda:CreateFunction",
"lambda:GetFunction",
"lambda:GetFunctionCodeSigningConfig",
"lambda:GetFunctionRecursionConfig",
"lambda:GetPolicy",
"lambda:GetRuntimeManagementConfig"
],
"Resource": "arn:aws:lambda:${Region}:${Account}:function:${FunctionName}"
}
]
}
次にリソースの指定箇所でエラーが出ているので、${StackName}などを手動で書き換えます。
SAMのプロジェクト名がそのままCloudFormationのスタック名になり、各種リソースは<スタック名>-<乱数>という形で命名されます。
その後エラーがなくなったことを確認し、ポリシーを作成およびアタッチでアタッチします。
アタッチが完了したら、最初に設定した強い権限は削除しておきます。
3.動作確認
IAM Access Analyzer Policy Generationで作ったポリシーのみで動作確認してみます。
これで動けば良いのですが、やはり一発では動きません。
ここからはトライ&エラーですので、対処した内容をまとめておきます。
s3:PutObject on resource: "arn:aws:s3:::aws-sam-cli-managed-default-samclisourcebucket-9zu1ysv6zu3b/63f0e671a9748582d98210805e858012" because no identity-based policy allows the s3:PutObject action
最初にSAMの部分でアーティファクトをアップロードできないよ!って言われます。
以下のドキュメントに通り、リソースの作成・削除以外のデータイベントはポリシー生成の対象にならないみたいです。
データイベントを使用できません — IAM Access Analyzer は、生成されたポリシーで、Amazon S3 データイベントなどのデータイベントのアクションレベルのアクティビティを識別しません。
ということなので、手動で以下を追加します。
PutしたらGetもするのでs3:GetObjectも付与しておきます。
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::aws-sam-cli-managed-default-samclisourcebucket-*/*"
}
cloudformation:CreateChangeSet on resource: arn:aws:cloudformation:ap-northeast-1:aws:transform/Serverless-2016-10-31 because no identity-based policy allows the cloudformation:CreateChangeSet action
次に見慣れないエラーが出てきました。
調べてみると、AWS SAMを使う場合は以下の権限が必要みたいです。
変更セットの作成を AWS::Serverless トランスフォームに許可するには、次のポリシーに示すように、arn:aws:cloudformation:region:aws:transform/Serverless-2016-10-31 リソースレベルのアクセス許可を含めます。
以下のページを見るとcloudformation:CreateChangeSetには対応しているみたいですが、ここには対応していないみたい。
ということなので、手動で以下を追加します。
{
"Effect": "Allow",
"Action": [
"cloudformation:CreateChangeSet"
],
"Resource": "arn:aws:cloudformation:ap-northeast-1:aws:transform/Serverless-2016-10-31"
}
iam:GetRole on resource: role policy-generation-test-HelloWorldFunctionRole-4EXsLvEZCmXz because no identity-based policy allows the iam:GetRole action
次はIAM系のエラーです。
以下のように何度か失敗するので、その度に権限を付与していきます。
iam:GetRole
↓
iam:CreateRole
iam:DetachRolePolicy(ロールバック時に利用)
↓
iam:TagRole
↓
iam:AttachRolePolicy
iam:DeleteRole(ロールバック時に利用)
↓
iam:PassRole
結果、以下のようなポリシーを付与しました。
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole",
"iam:CreateRole",
"iam:TagRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:DeleteRole"
],
"Resource": "arn:aws:iam::111122223333:role/policy-generation-test-*"
}
lambda:TagResource on resource: arn:aws:lambda:ap-northeast-1:853835738220:function:policy-generation-test-HelloWorldFunction-qF1xJaXrnvf2 because no identity-based policy allows the lambda:TagResource action
lambda自体はサポートしているのですが、lambda:TagResourceが対応していないみたいなので、ここも手動対応します。
また、ロールバック時にlambda:DeleteFunction権限がないことでロールバックが失敗しちゃうので、合わせて権限付与しました。
{
"Effect": "Allow",
"Action": [
"lambda:AddPermission",
"lambda:CreateFunction",
"lambda:GetFunction",
"lambda:GetFunctionCodeSigningConfig",
"lambda:GetFunctionRecursionConfig",
"lambda:GetPolicy",
"lambda:GetRuntimeManagementConfig",
"lambda:UpdateFunctionCode",
+ "lambda:TagResource",
+ "lambda:DeleteFunction"
],
"Resource": "arn:aws:lambda:ap-northeast-1:853835738220:function:policy-generation-test-*"
}
arn:aws:apigateway:ap-northeast-1::/restapis because no identity-based policy allows the apigateway:POST action
最後にAPI Gatewayです。
apigatewayもポリシー生成の対象外なので、手動で追加していきます。
ここも似たエラーを繰り返し発生し、結局以下のような権限が必要でした。
{
"Effect": "Allow",
"Action": [
"apigateway:POST",
"apigateway:PUT",
"apigateway:DELETE",
"apigateway:PATCH",
"apigateway:GET"
],
"Resource": "arn:aws:apigateway:ap-northeast-1::/restapis*"
},
まとめ
アプローチとしてはとても便利だなと思いつつ、データイベント未対応、全てのサービスあるいはアクションに対応していないところが痛いですね。
今回の検証でも、10回以上のトライアンドエラーを繰り返し、それなりの時間を要してしまいました。
一から設定していくよりは早いですが、今後ポリシー自動生成の対応範囲が増えていくことを期待します!











