症状
S3へのアクセスで Access Denied (403) が返る。コンソールでもCLIでも起きうる、AWSで最も遭遇率の高いエラーのひとつです。
チェックリスト(上から順に確認)
1. 「今、誰として」実行しているか
aws sts get-caller-identity
想定と違うプロファイル・古い認証情報で実行しているケースが原因の3割を占めます。まずここから。
2. IAMポリシー(呼び出し側)
- そのプリンシパルに必要な Action が許可されているか
-
ARNの粒度を間違えていないか(定番のハマり)
-
s3:ListBucket→ バケット本体arn:aws:s3:::my-bucketへの権限 -
s3:GetObject→ オブジェクトarn:aws:s3:::my-bucket/*への権限 -
/*だけ書いて List 系が落ちる、が最頻出です
-
3. バケットポリシー(リソース側)
aws s3api get-bucket-policy --bucket my-bucket
明示的な Deny がないか。IAMでAllowしてもリソース側のDenyが勝ちます。
4. ブロックパブリックアクセス設定
公開アクセスを想定している場合、アカウント設定またはバケット設定でブロックされていないか。
5. 暗号化キー(KMS)の権限
SSE-KMSで暗号化されたオブジェクトは、S3の権限に加えてKMSキーへの権限(kms:Decrypt 等)が必要。暗号化バケットでのAccess Deniedの隠れた定番です。
6. VPCエンドポイントポリシー
プライベートサブネットからVPCエンドポイント経由でアクセスしている場合、エンドポイント側のポリシーでも絞られます。
7. クロスアカウントの場合は「両側」
呼ぶ側のIAM許可+呼ばれる側のバケットポリシー許可、の両方が必要です。
それでも解決しないとき
- IAM Policy Simulator でどの評価で落ちるか確認
- CloudTrail で実際のエラーイベント(
errorCode: AccessDenied)を確認 - Organizations 配下なら SCP のガードレールを疑う
S3の設計・活用の全体像(ストレージクラス、ライフサイクル、OACによる保護など)はZennにまとめています:
https://zenn.dev/naoto_tech_AI/articles/aws-09-s3-is-not-just-storage