こんにちは、インフラエンジニアのryuです。
AWSでCLIを実行したり、コンソールでボタンを押したりしたときに、AccessDenied や is not authorized to perform というエラーが出ることがあります。権限が足りないのは分かるものの、どのポリシーを直せばいいのかが分からず、とりあえず強い権限を付けてしまう人も多いと思います。
結論から言うと、AccessDeniedは次の順番で調べると原因を絞り込みやすくなります。エラー文を読んで「誰が・何を・どこに」を確かめ、aws sts get-caller-identity で今の自分が誰なのかを確認し、エラー文に書かれたポリシーの種類から調べる場所を決めます。エラー文だけで分からないときは、CloudTrailで失敗した呼び出しの記録を探します。
この記事は、IAMの基本(ユーザー・ロール・ポリシー)を一度は触ったことがある方を想定しています。CLIの例は、AWS CLI v2が設定済みの環境で実行する前提です。
AccessDeniedが出たら、まずエラー文を最後まで読む¶
AccessDeniedのエラー文には、思っているより多くの情報が入っています。読み飛ばして権限を足す前に、まず文章を区切って読んでみてください。
エラー文の形と、読み取る3つの情報¶
AWSの公式ドキュメントによると、多くのサービスのアクセス拒否のメッセージは、次の形になっています。
User: <誰が> is not authorized to perform: <どの操作を> on resource: <どのリソースに> because <理由>
公式ドキュメントに載っている例は、User: arn:aws:iam::123456789012:user/mateojackson is not authorized to perform: widgets:GetWidget on resource: my-example-widget のようなものです。ここから読み取るのは次の3つです。
| 部分 | 読み取ること | よくある勘違い |
|---|---|---|
User: の後ろのARN |
リクエストを出した主体 | 自分のIAMユーザーだと思っていたら、実はロールだった |
perform: の後ろ |
拒否された操作(サービス名:アクション名) |
画面の操作名とAPIのアクション名は違うことがある |
on resource: の後ろ |
対象のリソース | ポリシーの Resource が別のARNを指している |
特に1つ目は大事です。EC2の上で動くプログラムやLambdaから実行している場合、エラーに出てくるのはIAMユーザーではなく、assumed-role を含むロールのセッションです。直す相手を間違えると、いくらポリシーを足しても結果は変わりません。
なお、公式ドキュメントにも書かれていますが、すべてのサービスがこの形のメッセージを返すわけではありません。EC2のように、理由の部分を暗号化して返すサービスもあります(後ほど扱います)。
「no ... policy allows」と「explicit deny」は意味が違う¶
エラー文の because の後ろには、拒否の理由が書かれていることがあります。ここで見分けたいのが、次の2種類です。
1つ目は because no identity-based policy allows the ... action のような書き方です。これは、許可するポリシーが1つも無かったという意味で、暗黙的な拒否(implicit deny) と呼ばれます。AWSは、何も許可されていない操作を最初から拒否する仕組みなので、許可を足せば通る可能性があります。
2つ目は with an explicit deny in a service control policy のような書き方です。これは、どこかのポリシーに Deny の文があり、それに当てはまったという意味です。明示的な拒否(explicit deny)は、ほかのどのポリシーの許可よりも優先されます。 そのため、IAMユーザーやロールに許可を足しても通りません。
この違いを知っているだけで、調べる方向が大きく変わります。暗黙的な拒否なら足りない許可を探し、明示的な拒否なら Deny を書いたポリシーを探す、という分け方です。
AWSが許可・拒否を決める順番をおさえる¶
エラー文のポリシーの種類を読むには、AWSがリクエストをどう評価しているかを知っておくと楽になります。細かい条件は多いのですが、同じアカウントの中での基本は次のとおりです。
- まず、どこかのポリシーに当てはまる
Denyがあれば、その時点で拒否になる - 次に、組織のSCP(サービスコントロールポリシー)やアクセス許可の境界など、上限を決めるポリシーがあれば、その範囲に入っていないと拒否になる
- そのうえで、アイデンティティベースのポリシー(ユーザーやロールに付けたポリシー)か、リソースベースのポリシー(S3のバケットポリシーなど)のどちらかで許可されていれば通る
- どれにも許可が無ければ、暗黙的な拒否になる
ここで注意したいのは、SCPやアクセス許可の境界は「上限」を決めるだけで、それ自体は何も許可しない点です。SCPで許可されていても、ユーザーやロールのポリシーに許可が無ければ通りません。
また、公式ドキュメントには例外も書かれています。同じアカウント内で、リソースベースのポリシーがIAMユーザーやセッションのプリンシパルに直接許可を与えている場合は、アイデンティティベースのポリシーなどに許可が無くても通ることがあります。一方、ロールのARNに許可を与えた場合は、アクセス許可の境界やセッションポリシーの制限を受けます。細かい挙動が気になる場合は、末尾の参考にある公式の評価ロジックのページを確認してください。
IAMの基本的な用語に自信がない方は、IAMとは?IAMの概要や機能の解説や、IAMユーザーとIAMロールの違いを先に読んでおくと、この後の話が分かりやすくなります。
手順1:今の自分が誰なのかを確かめる¶
最初に確かめるのは、リクエストを出しているのが誰かです。CLIでは、次のコマンドで確認できます。
aws sts get-caller-identity
結果は UserId・Account・Arn の3つの項目を持つJSONで返ってきます。公式ドキュメントによると、この操作には権限が必要ありません。ポリシーで拒否されていても、同じ情報が返ってきます。なので、権限エラーで困っているときでも、まずこれを打てば本人確認ができます。
結果の Arn は次のように読み分けます(説明用の形で、実際の値は環境によって違います)。
Arn の形 |
意味 | 直す相手 |
|---|---|---|
arn:aws:iam::<アカウントID>:user/<ユーザー名> |
IAMユーザーとして実行している | そのIAMユーザー(またはグループ)のポリシー |
arn:aws:sts::<アカウントID>:assumed-role/<ロール名>/<セッション名> |
ロールを引き受けたセッションで実行している | そのロールのポリシー |
ここでよくあるのが、思っていたのと違うプロファイルや認証情報が使われているケースです。環境変数 AWS_PROFILE や AWS_ACCESS_KEY_ID が残っていたり、EC2のインスタンスプロファイルの権限で動いていたりすると、自分のつもりで別の主体が実行しています。
Account の値も見ておきましょう。検証用と本番用でアカウントを分けている場合、別のアカウントに向けてコマンドを打っていて、リソースが見つからない・権限が無いという結果になることがあります。
手順2:エラー文のポリシーの種類から、調べる場所を決める¶
本人が分かったら、エラー文の理由の部分を見て、どのポリシーを調べるかを決めます。エラー文に出てくる代表的なポリシーの種類と、調べる場所をまとめます。
| エラー文に出る種類 | 何のポリシーか | 主に調べる場所・相談先 |
|---|---|---|
| identity-based policy | ユーザー・グループ・ロールに付けたポリシー | IAMコンソールのその主体の「許可」タブ |
| permissions boundary | アクセス許可の境界(上限) | その主体に設定された境界のポリシー |
| session policy | ロールを引き受けるときに渡したポリシー | AssumeRole を呼ぶ側の設定やツール |
| resource-based policy | S3のバケットポリシーなど、リソース側のポリシー | 対象リソースのポリシー |
| service control policy | AWS Organizationsで組織が決めた上限 | 組織の管理者 |
| VPC endpoint policy | VPCエンドポイントに付けたポリシー | ネットワークの構成を管理している人 |
公式ドキュメントでも、エラー文にポリシーの種類が書かれている場合は、その種類のポリシーに絞って調べるように案内されています。順番に全部を見るより、ずっと早く原因にたどり着けます。
identity-based policyの場合は、アクションとリソースを突き合わせる¶
no identity-based policy allows と出たら、ユーザーやロールに付いているポリシーに、その操作の許可が無いということです。ポリシーを開いて、次の2点を確かめます。
1つ目は Action です。エラー文に出た s3:PutObject のようなアクション名が、ポリシーに含まれているかを見ます。コンソールの1つの操作の裏で、複数のAPIが呼ばれていることもあるので、エラー文に出た名前をそのまま探すのが確実です。
2つ目は Resource です。アクションが許可されていても、対象のARNが違えば通りません。S3なら、バケットそのもの(arn:aws:s3:::バケット名)と中のオブジェクト(arn:aws:s3:::バケット名/*)は別のリソースとして扱われる点が、つまずきやすいところです。
ポリシーの書き方そのものは、IAMポリシーの作成方法の記事で手順を追って説明しています。
service control policyの場合は、自分では直せないと考える¶
with an explicit deny in a service control policy と出た場合は、組織のSCPで拒否されています。SCPはメンバーアカウントのIAMの設定では変えられないので、自分のアカウントの中でポリシーをいくら足しても通りません。
この場合は、エラー文の内容(主体・アクション・リソース・時刻)を添えて、組織の管理者に相談するのが正しい進め方です。よくあるのは、使ってよいリージョンを制限するSCPで、許可されていないリージョンに向けてコマンドを打っていたケースです。
resource-based policyの場合は、リソース側を見る¶
S3のバケットポリシーやKMSのキーポリシーのように、リソース側にもポリシーがあるサービスでは、そこで拒否されることがあります。特に、バケットポリシーに Deny が書かれていると、IAM側でどれだけ許可しても通りません。
リソースを作った人と使う人が違う場合は、リソース側のポリシーも見せてもらうようにしましょう。
手順3:暗号化されたメッセージはデコードして読む¶
EC2などでは、エラー文が You are not authorized to perform this operation. Encoded authorization failure message: ... のような形で返ってきて、理由が長い文字列に暗号化されています。AWSは、拒否の詳しい理由そのものが重要な情報になりうるため、こうして隠しています。
この文字列は、次のコマンドで読める形に戻せます。
aws sts decode-authorization-message \
--encoded-message "<エラーに出た長い文字列>" \
--query DecodedMessage --output text
結果のJSONには、拒否された操作、対象のリソース、そのときの条件キーの値などが入っています。SCPで拒否された場合は、どの文が当てはまったかを探す手がかりも含まれます。
ただし、このデコードには sts:DecodeAuthorizationMessage の許可が必要です。権限が無いと、デコードそのものがAccessDeniedになります。自分で実行できない場合は、許可を持っている管理者にデコードを頼んでください。
手順4:CloudTrailで失敗した呼び出しを探す¶
エラー文が手元に残っていない、プログラムの中で起きていて詳細が分からない、といった場合はCloudTrailを使います。CloudTrailは、AWSのAPIの呼び出しを記録するサービスです。
CloudTrailのイベント履歴は、アカウントを作った時点から使えるようになっていて、リージョンごとに直近90日分の管理イベントを見られます。イベント履歴を見ることには料金がかかりません。
CLIでは、たとえば次のように最近のイベントを取り出せます。
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances \
--max-results 20
取り出したイベントの中で、errorCode に AccessDenied や UnauthorizedOperation が入っているものが、失敗した呼び出しです。同じイベントの userIdentity で誰が実行したか、errorMessage で拒否の理由を確認できます。なお、この呼び出しはアカウント・リージョンごとに1秒2回までという制限があるので、ループで大量に呼ぶのは避けましょう。
ここで1つ注意があります。イベント履歴に出てくるのは管理イベントだけです。S3のオブジェクトの読み書きのようなデータイベントは、別途トレイルなどで記録を設定していないと見つかりません。「S3のPutObjectで拒否されたのに、CloudTrailに出てこない」というときは、まずこの点を疑ってください。
CloudTrailとCloudWatchの役割の違いは、CloudWatchとCloudTrailの違いの記事で整理しています。コンソールからイベントを探す操作は、CloudTrailでユーザーの操作ログを確認する方法が参考になります。
手順5:直したら、通ることを確かめる¶
原因が分かってポリシーを直したら、もう一度同じ操作を実行して通ることを確かめます。IAMの変更は反映に少し時間がかかることがあるので、直後に失敗しても、少し待ってから試してみてください。
本番で何度も試すのが不安な場合は、IAMポリシーシミュレーターを使うと、ポリシーを付けた状態で特定の操作が許可されるかを事前に確かめられます。アイデンティティベースのポリシーやアクセス許可の境界を試せますが、公式ドキュメントにあるとおり、条件付きのSCPやアカウントをまたぐアクセスは試せないなどの制限があります。シミュレーターの結果は目安として使い、最終的には実際の操作で確かめるのが確実です。
やってはいけない直し方¶
権限エラーが続くと、つい AdministratorAccess を付けたり、"Action": "*" や "Resource": "*" で全部を許可したりしたくなります。エラーは消えますが、原因を特定しないまま権限を広げたことになり、あとから絞り直すのが難しくなります。
また、明示的な拒否が原因の場合は、そもそも許可を足しても直りません。強い権限を付けても通らないときは、Deny の書かれたポリシーを探す方向に切り替えましょう。
調べ方の要点を、症状ごとにまとめておきます。
| 症状 | まず見るもの | 次の手 |
|---|---|---|
| 自分には権限があるはずなのに拒否される | get-caller-identity の Arn |
実際に使われている主体のポリシーを見る |
no identity-based policy allows |
ポリシーの Action と Resource |
足りない許可を、必要な範囲だけ足す |
explicit deny in a service control policy |
組織のSCP | 管理者に相談する |
| 理由が暗号化されている | decode-authorization-message |
デコード結果の操作・リソース・条件を見る |
| エラー文が残っていない | CloudTrailのイベント履歴 | errorCode と userIdentity を確認する |
InfraAcademyで、AWSの権限の仕組みを順番に学ぶ¶
AccessDeniedの切り分けは、IAMの用語を覚えるだけでは身につきにくく、ユーザー・ロール・ポリシー・ログがどうつながっているかを理解して、初めてスムーズにできるようになります。
InfraAcademy のAWSロードマップでは、IAMやEC2、S3といった基本のサービスから順番に学べるようにしています。現場でエラーに出会ったのをきっかけに、AWSの基礎を体系的に学び直したい方は参考にしてみてください。実際に手を動かして確認したい方は、AWS初心者向けのハンズオンの記事もあわせてどうぞ。
まとめ¶
AWSのAccessDeniedは、闇雲に権限を足すより、順番に絞り込むほうが早く直ります。エラー文から「誰が・何を・どこに」を読み、aws sts get-caller-identity で実際の主体を確かめ、エラー文に書かれたポリシーの種類から調べる場所を決めます。
暗黙的な拒否なら足りない許可を探し、明示的な拒否なら Deny を書いたポリシーを探します。エラー文が暗号化されていればデコードし、手元に情報が無ければCloudTrailのイベント履歴で失敗した呼び出しを探しましょう。
次にAccessDeniedが出たら、ポリシーを開く前に aws sts get-caller-identity を1回打ってみてください。それだけで、直す相手を間違えることがかなり減るはずです。
参考¶
- Troubleshoot access denied error messages(AWS Identity and Access Management ユーザーガイド)
- Policy evaluation logic(AWS Identity and Access Management ユーザーガイド)
- How AWS enforcement code logic evaluates requests to allow or deny access(AWS Identity and Access Management ユーザーガイド)
- GetCallerIdentity(AWS Security Token Service API Reference)
- decode-authorization-message(AWS CLI Command Reference)
- How can I get data to assist in troubleshooting IAM permission access denied or unauthorized errors?(AWS Knowledge Center)
- Working with CloudTrail event history(AWS CloudTrail ユーザーガイド)
- IAM policy testing with the IAM policy simulator(AWS Identity and Access Management)



