- AWS
AWS AccessDeniedの原因と対処|エラー文別の切り分け表
AWS の AccessDenied とは、リクエストを評価した結果「許可する文がどこにもない(暗黙的な拒否)」か「拒否する文に当たった(明示的な拒否)」のどちらかになったことを知らせるエラーです。 どのポリシーが理由なのかは、エラー文の末尾に書かれています。末尾を読めば、見るべき場所が1つに絞れます。
この記事では、エラー文の末尾ごとに「原因・確認コマンド・直し方」を並べた切り分け表を用意し、実行主体の確認からポリシーの一覧取得、符号化されたメッセージの解読までを、コマンドと出力つきで順番に示します。
確認環境:Ubuntu 24.04 / AWS CLI 1.46.1 / Python 3.11 / boto3 1.43。コマンドは AWS の API をローカルで再現するツール(moto 5.2.3)で実行し、エラー文は AWS 公式ドキュメントの記載を引用しています。掲載したコマンドは、ローカルの接続先を指定するオプション(--endpoint-url)を外し、実際の AWS でそのまま使える形にしています。
AccessDeniedの早見表(エラー文の末尾で切り分ける)
エラー文は次の形をしています。見るのは「誰が」「何を」「どこに」「なぜ」の4か所です。
User: arn:aws:iam::123456789012:user/app-deploy ← 誰が(実行主体)
is not authorized to perform: s3:GetObject ← 何を(足りないアクション)
on resource: "arn:aws:s3:::example-bucket/a.txt" ← どこに(対象リソース)
because no identity-based policy allows the s3:GetObject action ← なぜ(末尾)
末尾は大きく2種類です。
| 末尾の形 | 意味 | 直す方向 |
|---|---|---|
because no ~ allows the ~ action |
暗黙的な拒否。そのポリシーに許可する文がない | Allow を足す |
with an explicit deny in ~ |
明示的な拒否。Deny の文に当たった | Deny の文か条件を見直す |
末尾ごとの切り分け表です(エラー文は AWS 公式ドキュメントの記載にもとづきます)。
| 末尾に出る言葉 | 原因になっているポリシー | 確認コマンド | 直し方 |
|---|---|---|---|
no identity-based policy allows |
ユーザー・グループ・ロールに付けたポリシーに Allow がない | aws iam list-attached-user-policies / list-user-policies / list-groups-for-user(ロールは list-attached-role-policies / list-role-policies) |
足りないアクションを Allow するポリシーを付ける |
explicit deny in an identity-based policy |
付けたポリシーのどれかに Deny がある(ポリシーの ARN が続くことがある) | aws iam get-policy-version で JSON を読む |
Deny の文、または Condition を見直す |
no service control policy allows |
AWS Organizations の SCP に Allow がない | aws organizations list-policies-for-target --filter SERVICE_CONTROL_POLICY |
組織の管理者に SCP への Allow 追加を依頼する |
explicit deny in a service control policy |
SCP の Deny に当たった(リージョン制限など) | aws organizations describe-policy |
SCP の Deny や条件を管理者と見直す。アカウント内の IAM では上書きできない |
explicit deny in a resource control policy |
AWS Organizations の RCP の Deny に当たった | aws organizations list-policies-for-target --filter RESOURCE_CONTROL_POLICY |
RCP の Deny を管理者と見直す |
no permissions boundary allows |
アクセス許可の境界(permissions boundary)に Allow がない | aws iam get-user --query User.PermissionsBoundary / aws iam get-role --query Role.PermissionsBoundary |
境界に使っているポリシーへ Allow を足す |
explicit deny in a permissions boundary |
境界のポリシーに Deny がある | 上と同じコマンドで ARN を調べ、get-policy-version で読む |
境界のポリシーの Deny を見直す |
no resource-based policy allows |
リソース側のポリシー(バケットポリシー、キーポリシーなど)に Allow がない | aws s3api get-bucket-policy / aws lambda get-policy / aws kms get-key-policy |
リソース側のポリシーに実行主体への Allow を足す |
explicit deny in a resource-based policy |
リソース側のポリシーに Deny がある | 上と同じ | Deny の文、または Condition を見直す |
no session policy allows |
AssumeRole などで渡したセッションポリシーに Allow がない | セッションを作った処理の --policy / --policy-arns を確認 |
セッションポリシーに Allow を足して、セッションを作り直す |
explicit deny in a session policy |
セッションポリシーに Deny がある | 上と同じ | セッションポリシーの Deny を見直す |
no role trust policy allows the sts:AssumeRole action |
ロールの信頼ポリシーに、呼び出し元への Allow がない | aws iam get-role --query Role.AssumeRolePolicyDocument |
信頼ポリシーの Principal に呼び出し元を足す |
explicit deny in the role trust policy |
信頼ポリシーに Deny がある | 上と同じ | 信頼ポリシーの Deny を見直す |
no VPC endpoint policy allows / explicit deny in a VPC endpoint policy |
VPC エンドポイントのポリシー | aws ec2 describe-vpc-endpoints で PolicyDocument を読む |
エンドポイントポリシーを見直す |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS AccessDeniedの原因と対処|エラー文別の切り分け表」
許可と拒否の評価順を1枚の図でつかむ
AWS は、1つのリクエストに関係するポリシーをすべて集めて評価します。どこか1か所でも Deny があれば拒否、Deny がなければ各段階で Allow が見つかるかを順に確かめる、という流れです(AWS 公式ドキュメント「Policy evaluation logic」の同一アカウント内の流れにもとづく図です)。
flowchart TD
A[リクエスト] --> B{どこかのポリシーに<br>当てはまる Deny がある}
B -- ある --> X1[拒否<br>explicit deny in ...]
B -- ない --> C{RCP に Allow がある}
C -- ない --> X2[拒否]
C -- ある --> D{SCP に Allow がある}
D -- ない --> X3[拒否<br>no service control policy allows]
D -- ある --> E{リソースベースのポリシーが<br>実行主体を Allow している}
E -- している --> OK1[許可]
E -- していない --> F{アイデンティティベースの<br>ポリシーに Allow がある}
F -- ない --> X4[拒否<br>no identity-based policy allows]
F -- ある --> G{permissions boundary が<br>あり Allow していない}
G -- はい --> X5[拒否<br>no permissions boundary allows]
G -- いいえ --> H{セッションポリシーが<br>あり Allow していない}
H -- はい --> X6[拒否<br>no session policy allows]
H -- いいえ --> OK2[許可]
図から読み取れる要点は3つです。
| 要点 | 内容 |
|---|---|
| Deny が最優先 | SCP・RCP・リソース側・アイデンティティ側・境界・セッションのどこにあっても、当てはまる Deny が1つあれば拒否になる |
| 組織のポリシーと境界は「上限」 | SCP・RCP・permissions boundary・セッションポリシーは権限を与えず、使える範囲を絞るだけ。アイデンティティ側の Allow と両方が必要 |
| リソース側の Allow は同一アカウントなら単独で通ることがある | リソースベースのポリシーが IAM ユーザーの ARN やロールのセッションを直接 Allow していれば、アイデンティティ側に Allow がなくても許可される |
別のアカウントのリソースを使うときは、呼び出す側のアイデンティティベースのポリシーと、リソース側のポリシーの両方に Allow が必要です。
手順1:誰として実行しているかを確かめる
最初に確かめるのは実行主体です。想定と違うユーザーやロールで実行していると、ポリシーをいくら直しても結果が変わりません。
aws sts get-caller-identity --query Arn --output text
arn:aws:iam::123456789012:user/app-deploy
ARN の形で、主体の種類が分かります。
| ARN の形 | 主体 | ポリシーを調べる対象 |
|---|---|---|
arn:aws:iam::123456789012:user/app-deploy |
IAM ユーザー | ユーザー本人と、所属グループ |
arn:aws:sts::123456789012:assumed-role/app-role/セッション名 |
ロールを引き受けたセッション | ロール app-role(セッション名ではなくロール名で調べる) |
arn:aws:iam::123456789012:root |
ルートユーザー | IAM ポリシーではなく SCP を確認 |
エラー文の User: に出ている ARN と、このコマンドの結果が同じかどうかも見ておきます。Lambda 関数や EC2 の中で起きたエラーなら、User: には関数やインスタンスに割り当てたロールが出ます。
手順2:付いているポリシーを一覧する
IAM ユーザーの権限は「直接付けた管理ポリシー」「インラインポリシー」「所属グループのポリシー」の3か所に分かれています。3か所すべてを見るのがポイントです。
# 1. ユーザーに直接付けた管理ポリシー
aws iam list-attached-user-policies --user-name app-deploy
# 2. ユーザーのインラインポリシー
aws iam list-user-policies --user-name app-deploy
# 3. 所属グループ
aws iam list-groups-for-user --user-name app-deploy --query 'Groups[].GroupName'
{
"AttachedPolicies": [
{
"PolicyName": "app-deploy-read",
"PolicyArn": "arn:aws:iam::123456789012:policy/app-deploy-read"
}
]
}
{
"PolicyNames": [
"inline-logs"
]
}
[
"developers"
]
グループにも管理ポリシーとインラインポリシーの2種類があります。
aws iam list-attached-group-policies --group-name developers
aws iam list-group-policies --group-name developers
{
"AttachedPolicies": []
}
{
"PolicyNames": [
"group-sqs-read"
]
}
この例では、グループの管理ポリシーは空で、インラインポリシー group-sqs-read だけが付いていました。片方だけを見て「何も付いていない」と判断しないようにします。
ロールの場合は次の2つです。
aws iam list-attached-role-policies --role-name app-role
aws iam list-role-policies --role-name app-role
ポリシーの中身(JSON)を読む
管理ポリシーは、既定のバージョン番号を調べてから中身を取り出します。
aws iam get-policy \
--policy-arn arn:aws:iam::123456789012:policy/app-deploy-read \
--query Policy.DefaultVersionId
"v1"
aws iam get-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/app-deploy-read \
--version-id v1 --query PolicyVersion.Document
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"sts:GetCallerIdentity",
"iam:List*",
"iam:Get*"
],
"Resource": "*"
}
]
}
インラインポリシーは名前を指定して取り出します。
aws iam get-user-policy --user-name app-deploy \
--policy-name inline-logs --query PolicyDocument
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:DescribeLogGroups",
"Resource": "*"
}
]
}
このユーザーに許可されている S3 のアクションは s3:ListAllMyBuckets だけです。バケットの一覧は取れますが、バケットの中身を見る s3:ListBucket や、オブジェクトを読む s3:GetObject は含まれていません。エラー文の「足りないアクション」と、ここで読んだ Action を見比べれば、足すべきものが決まります。
手順3:境界・組織・リソース側のポリシーを確認する
エラー文の末尾がアイデンティティベース以外を指しているときは、次のコマンドで該当するポリシーを取り出します。
permissions boundary(アクセス許可の境界)
aws iam get-user --user-name app-deploy --query User.PermissionsBoundary
aws iam get-role --role-name app-role --query Role.PermissionsBoundary
null
{
"PermissionsBoundaryType": "PermissionsBoundaryPolicy",
"PermissionsBoundaryArn": "arn:aws:iam::123456789012:policy/app-read"
}
null なら境界は設定されていません。ARN が返ったら、そのポリシーを get-policy-version で読みます。境界に含まれないアクションは、ロールに AdministratorAccess を付けていても通りません。
SCP(サービスコントロールポリシー)
組織の管理アカウント、または委任された管理者の権限で実行します。
aws organizations list-policies-for-target --target-id 123456789012 \
--filter SERVICE_CONTROL_POLICY --query 'Policies[].[Id,Name]' --output text
p-FullAWSAccess FullAWSAccess
p-7e1jwjed deny-outside-tokyo
aws organizations describe-policy --policy-id p-7e1jwjed \
--query Policy.Content --output text
{"Version":"2012-10-17","Statement":[{"Sid":"DenyOutsideTokyo","Effect":"Deny","Action":"ec2:*","Resource":"*","Condition":{"StringNotEquals":{"aws:RequestedRegion":"ap-northeast-1"}}}]}
この SCP が付いたアカウントでは、東京リージョン以外の EC2 操作が explicit deny in a service control policy になります。SCP はアカウントそのもののほか、上位の OU やルートにも付けられるので、--target-id を OU の ID に変えて同じコマンドを実行します。
リソースベースのポリシー
| サービス | 取り出すコマンド |
|---|---|
| S3 バケット | aws s3api get-bucket-policy --bucket example-bucket --query Policy --output text |
| Lambda 関数 | aws lambda get-policy --function-name resize-image --query Policy --output text |
| KMS キー | aws kms get-key-policy --key-id キーID --policy-name default --query Policy --output text |
| IAM ロール(信頼ポリシー) | aws iam get-role --role-name app-role --query Role.AssumeRolePolicyDocument |
S3 バケットで実行した例です。
aws s3api get-bucket-policy --bucket example-bucket --query Policy --output text
{"Version":"2012-10-17","Statement":[{"Sid":"DenyDelete","Effect":"Deny","Principal":"*","Action":"s3:DeleteObject","Resource":"arn:aws:s3:::example-bucket/*"}]}
このバケットでは、IAM 側で s3:* を許可していても、削除だけは explicit deny in a resource-based policy になります。
KMS のキーポリシーも同じ要領で取り出せます。
aws kms get-key-policy --key-id 22c8c245-abb2-4df5-84a3-727cc3ab17f5 \
--policy-name default --query Policy --output text
{"Version": "2012-10-17", "Id": "key-default-1", "Statement": [{"Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::123456789012:root"}, "Action": "kms:*", "Resource": "*"}]}
Principal がアカウントの root になっているこの文が、「このキーへのアクセスを IAM ポリシーで決めてよい」という委任にあたります。
セッションポリシー
assume-role に --policy を渡すと、そのセッションで使える権限がロールの権限とセッションポリシーの重なる部分だけになります。
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/app-role \
--role-session-name limited \
--policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"*"}]}' \
--query AssumedRoleUser.Arn
"arn:aws:sts::123456789012:assumed-role/app-role/limited"
このセッションで s3:PutObject を呼ぶと、ロールに許可があっても no session policy allows になります。セッションを作っているスクリプトやツールの設定に --policy や --policy-arns がないかを見ます。
手順4:符号化されたメッセージを decode-authorization-message で読む
EC2 などの一部の操作では、拒否の理由が長い符号化された文字列(encoded message)で返ります。これは sts decode-authorization-message で読める形に戻せます。実行には sts:DecodeAuthorizationMessage の許可が必要です。
aws sts decode-authorization-message \
--encoded-message "エラーに含まれていた長い文字列" > decoded.json
返ってくる DecodedMessage は、JSON を文字列にしたものです。AWS CLI 公式リファレンスの出力例は次の形をしています(条件キーを3つに絞っています)。
{
"DecodedMessage": "{\"allowed\":false,\"explicitDeny\":true,\"matchedStatements\":{\"items\":[{\"statementId\":\"VisualEditor0\",\"effect\":\"DENY\",\"principals\":{\"items\":[{\"value\":\"AROA123456789EXAMPLE\"}]},\"principalGroups\":{\"items\":[]},\"actions\":{\"items\":[{\"value\":\"ec2:RunInstances\"}]},\"resources\":{\"items\":[{\"value\":\"*\"}]},\"conditions\":{\"items\":[]}}]},\"failures\":{\"items\":[]},\"context\":{\"principal\":{\"id\":\"AROA123456789EXAMPLE:Ana\",\"arn\":\"arn:aws:sts::111122223333:assumed-role/Developer/Ana\"},\"action\":\"RunInstances\",\"resource\":\"arn:aws:ec2:us-east-1:111122223333:instance/*\",\"conditions\":{\"items\":[{\"key\":\"ec2:InstanceMarketType\",\"values\":{\"items\":[{\"value\":\"on-demand\"}]}},{\"key\":\"aws:Region\",\"values\":{\"items\":[{\"value\":\"us-east-1\"}]}},{\"key\":\"ec2:InstanceType\",\"values\":{\"items\":[{\"value\":\"t2.micro\"}]}}]}}}"
}
このままでは読みにくいので、要点だけを取り出すスクリプトを用意しました。上の JSON を decoded.json に保存して実行した結果です。
# read_decoded.py
import json
import sys
outer = json.load(sys.stdin) # decode-authorization-message の出力
msg = json.loads(outer["DecodedMessage"]) # 中身は JSON を文字列にしたもの
print("許可されたか :", msg["allowed"])
print("明示的な拒否 :", msg["explicitDeny"])
print("実行主体 :", msg["context"]["principal"]["arn"])
print("アクション :", msg["context"]["action"])
print("リソース :", msg["context"]["resource"])
for st in msg["matchedStatements"]["items"]:
actions = [a["value"] for a in st["actions"]["items"]]
print("一致した文 :", st["statementId"], st["effect"], actions)
for c in msg["context"]["conditions"]["items"]:
values = [v["value"] for v in c["values"]["items"]]
print("条件キー :", c["key"], "=", values)
python3 read_decoded.py < decoded.json
許可されたか : False
明示的な拒否 : True
実行主体 : arn:aws:sts::111122223333:assumed-role/Developer/Ana
アクション : RunInstances
リソース : arn:aws:ec2:us-east-1:111122223333:instance/*
一致した文 : VisualEditor0 DENY ['ec2:RunInstances']
条件キー : ec2:InstanceMarketType = ['on-demand']
条件キー : aws:Region = ['us-east-1']
条件キー : ec2:InstanceType = ['t2.micro']
読み方は次のとおりです。
| 項目 | 見るポイント |
|---|---|
explicitDeny |
true なら Deny の文に当たっている。false なら Allow が足りない |
matchedStatements |
当たった文の Sid(statementId)。この Sid を手がかりにポリシーを探す |
context.conditions |
リクエストに含まれていた条件キーの値。Condition と見比べる |
この例は、Sid が VisualEditor0 の Deny 文が ec2:RunInstances を止めている、と読めます。
手順5:直す前にシミュレーターで確かめる
ポリシーを書き換える前に、iam simulate-principal-policy で「このユーザーがこのアクションを実行できるか」を調べられます。AWS CLI 公式リファレンスの例です。
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/alejandro \
--action-names codecommit:ListRepositories
結果の EvalDecision は次の3つのどれかになります。
| EvalDecision | 意味 |
|---|---|
allowed |
許可される |
implicitDeny |
Allow する文がない |
explicitDeny |
Deny する文に当たった |
MatchedStatements には、判定に使われたポリシーの名前と行番号が入ります。ユーザーを指定すると所属グループのポリシーも含めて評価され、--resource-arns で対象リソースを絞ることもできます。
S3・Lambda・KMS・AssumeRoleでよく出るエラーと足りないもの
サービスごとに、つまずきやすい組み合わせを表にしました(AWS 公式ドキュメントの各サービスのトラブルシューティングにもとづきます)。
S3
| 起きること | 足りないもの・確認する場所 |
|---|---|
is not authorized to perform: s3:GetObject because no identity-based policy allows the s3:GetObject action |
アイデンティティ側に s3:GetObject の Allow。Resource はオブジェクトの ARN(arn:aws:s3:::example-bucket/*)で書く |
| バージョン ID を指定した取得だけが通らない | s3:GetObjectVersion。バージョン ID つきの取得では s3:GetObject ではなくこちらが要る |
| 存在しないキーを取得すると 404 ではなく 403 になる | バケットへの s3:ListBucket があれば 404、なければ 403 が返る。キー名の誤りも候補に入れる |
| SSE-KMS で暗号化したオブジェクトで拒否される | IAM ポリシーとキーポリシーの両方に kms:Decrypt と kms:GenerateDataKey |
| リクエスタ支払いのバケットで拒否される | リクエストに --request-payer requester を付ける |
理由の付かない Access Denied だけが返る |
別アカウントかつ別組織からのリクエストでは、詳しい理由が付かない。呼び出し側とバケット側の両方のポリシーを確認する |
| ポリシーは合っているのに公開アクセスが通らない | ブロックパブリックアクセスの設定(aws s3api get-public-access-block) |
S3 では、同じアカウント内、または同じ組織内のリクエストに限り、末尾に理由が付いた詳しいエラー文が返ります。
Lambda
| 起きること | 足りないもの・確認する場所 |
|---|---|
is not authorized to perform: iam:PassRole |
関数に実行ロールを渡す操作(作成や設定変更)には、操作する人に iam:PassRole が要る。Resource は渡すロールの ARN |
is not authorized to perform: lambda:~ on resource: ~ |
操作する人のポリシーに、その Lambda アクションの Allow |
| ほかのサービスやアカウントから関数を呼べない | 関数のリソースベースのポリシー(aws lambda get-policy)に、呼び出し元への lambda:InvokeFunction |
| 関数の中の処理が AccessDenied になる | User: に出るのは関数の実行ロール。そのロールに足りないアクションを足す |
KMS
| 起きること | 足りないもの・確認する場所 |
|---|---|
IAM ポリシーで kms:Decrypt を許可したのに拒否される |
キーポリシーが IAM ポリシーへの委任(アカウントの root を Principal にした Allow)を含んでいるか。KMS はキーポリシー・IAM ポリシー・グラントのどれにも許可がなければ拒否になる |
| 別アカウントのキーが使えない | キーポリシー側で相手アカウントを Allow し、相手アカウント側の IAM ポリシーでも Allow する |
| グラントで許可しているはずが通らない | aws kms list-grants --key-id キーID で、対象の主体と操作を確認 |
AssumeRole
| 起きること | 足りないもの・確認する場所 |
|---|---|
is not authorized to perform: sts:AssumeRole because no role trust policy allows the sts:AssumeRole action |
引き受けたいロールの信頼ポリシーの Principal に、呼び出し元(アカウントやロール)が入っているか |
is not authorized to perform: sts:AssumeRole(アイデンティティ側) |
呼び出し元のポリシーに、対象ロールの ARN を Resource にした sts:AssumeRole の Allow |
| 条件つきの信頼ポリシーで通らない | 外部 ID、送信元 IP、有効期限、タグなど Condition の内容を満たしているか |
| ロール名は合っているはずなのに通らない | ロール名は大文字と小文字を区別する |
| ロールからロールへ連続して切り替えたセッションがすぐ切れる | ロールの連鎖では、セッションは最長1時間 |
直す前と後:足りないアクションを足す
手順2の app-deploy に、バケットの中身を見る権限とオブジェクトを読む権限を足す例です。バケットへの操作とオブジェクトへの操作で、Resource の ARN を分けて書くのが要点です。
直す前(S3 は s3:ListAllMyBuckets だけ):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListAllMyBuckets", "sts:GetCallerIdentity", "iam:List*", "iam:Get*"],
"Resource": "*"
}
]
}
直した後(2つの文を追加):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListAllMyBuckets", "sts:GetCallerIdentity", "iam:List*", "iam:Get*"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::example-app-logs"
},
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-app-logs/*"
}
]
}
管理ポリシーは、新しいバージョンを作って既定にすると反映されます。
aws iam create-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/app-deploy-read \
--policy-document file://policy.json --set-as-default
切り分けのチェックリスト
| 順番 | 確認すること | コマンド |
|---|---|---|
| 1 | エラー文の User: と末尾を読む |
(エラー文) |
| 2 | 実行主体が想定どおりか | aws sts get-caller-identity |
| 3 | 足りないアクションが、付いているポリシーにあるか | list-attached-user-policies / list-user-policies / list-groups-for-user |
| 4 | Resource の ARN が対象と一致しているか(バケットとオブジェクトの書き分け、リージョン、アカウント ID) | get-policy-version |
| 5 | Condition(リージョン、MFA、タグ、送信元 IP)を満たしているか | get-policy-version |
| 6 | 境界が設定されていないか | get-user / get-role の PermissionsBoundary |
| 7 | 組織の SCP・RCP に当たっていないか | organizations list-policies-for-target |
| 8 | リソース側のポリシーと暗号化キーの設定 | get-bucket-policy / get-key-policy |
| 9 | 符号化されたメッセージがあれば解読する | sts decode-authorization-message |
よくある質問
Q. AdministratorAccess を付けているのに AccessDenied になるのはなぜですか?
A. アイデンティティベースのポリシーが全部を許可していても、SCP・RCP・permissions boundary・セッションポリシー・リソース側の Deny は別に評価されます。エラー文の末尾に、どれが理由かが出ています。末尾が explicit deny in a service control policy なら、組織の管理者に確認します。
Q. 暗黙的な拒否と明示的な拒否は、どう違いますか? A. 暗黙的な拒否は「Allow する文がない」状態で、Allow を足せば通ります。明示的な拒否は「Deny する文に当たった」状態で、Allow をいくら足しても通りません。Deny の文か、その Condition を見直します。
Q. ポリシーを直したのに、すぐには通りません。
A. まず aws sts get-caller-identity で、直したユーザーやロールで実行しているかを確かめます。ロールのセッションでセッションポリシーを使っている場合は、セッションを作り直します。
Q. エラー文に末尾の理由が付いていません。 A. サービスや状況によっては、理由の付かない短い文だけが返ります。S3 では、別アカウントかつ別組織からのリクエストがこれにあたります。その場合はチェックリストの順に、アイデンティティ側・リソース側・組織のポリシーを1つずつ確認します。
まとめ
- AccessDenied は、エラー文の末尾を読む。
because no ~ allowsは Allow の不足、with an explicit deny in ~は Deny に当たっている - 末尾に出るポリシーの種類(identity-based / service control policy / permissions boundary / resource-based / session policy)で、見る場所が1つに決まる
- 最初に
aws sts get-caller-identityで実行主体を確かめる。ロールのセッションなら、ロール名でポリシーを調べる - ユーザーの権限は3か所(管理ポリシー・インラインポリシー・グループ)に分かれているので、すべて一覧する
- Deny は最優先。SCP・境界・セッションポリシーは上限として働き、アイデンティティ側の Allow と両方が必要
- 符号化されたメッセージは
sts decode-authorization-messageで解読し、explicitDenyとmatchedStatementsを読む - S3 はバケットとオブジェクトで ARN を分け、KMS はキーポリシー、AssumeRole は信頼ポリシーも合わせて確認する
参考・出典
- AWS Identity and Access Management ユーザーガイド「Troubleshoot access denied error messages」 https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_access-denied.html
- AWS Identity and Access Management ユーザーガイド「How AWS enforcement code logic evaluates requests to allow or deny access」 https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic_policy-eval-denyallow.html
- AWS Identity and Access Management ユーザーガイド「Troubleshoot IAM roles」 https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_roles.html
- AWS CLI Command Reference「sts decode-authorization-message」 https://docs.aws.amazon.com/cli/latest/reference/sts/decode-authorization-message.html
- AWS CLI Command Reference「iam simulate-principal-policy」 https://docs.aws.amazon.com/cli/latest/reference/iam/simulate-principal-policy.html
- Amazon S3 ユーザーガイド「Troubleshoot access denied (403 Forbidden) errors in Amazon S3」 https://docs.aws.amazon.com/AmazonS3/latest/userguide/troubleshoot-403-errors.html
- Amazon S3 API Reference「GetObject」 https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html
- AWS Lambda デベロッパーガイド「Troubleshooting AWS Lambda identity and access」 https://docs.aws.amazon.com/lambda/latest/dg/security_iam_troubleshoot.html
- AWS Key Management Service デベロッパーガイド「Troubleshooting AWS KMS permissions」 https://docs.aws.amazon.com/kms/latest/developerguide/policy-evaluation.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS AccessDeniedの原因と対処|エラー文別の切り分け表」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。