AWS CLIにおける「Access Denied」と認証問題のトラブルシューティング
AWS Command Line Interface (CLI) の使用中にAccess Deniedエラーや予期せぬ認証失敗に遭遇することは、開発者やシステム管理者が直面する最も頻繁な障害の一つです。これらの問題は、ほぼ常にIdentity and Access Management (IAM) ポリシーの誤設定、一時的な認証情報の期限切れ、またはCLI環境の不正確なセットアップに起因しています。
これらのエラーをうまく解決するには、IDと認証情報の確認から始まり、詳細なIAMポリシーの評価へと進む体系的なアプローチが必要です。この包括的なガイドでは、AWS CLIにおける一般的な承認問題を迅速に特定し、修正するための実用的な手順と診断コマンドを提供し、リソースを効果的に管理できるようにします。
1. 初期診断:呼び出し元と認証情報の特定
複雑なポリシー分析に入る前に、最初に行うべきことは、AWS CLIがどの IAM IDを使用しているか、そしてその認証情報がまだ有効であるかを明確に確認することです。
現在のIDの確認: sts get-caller-identity
これは最も重要な診断コマンドです。後続のAWSコマンドを実行しているUser ARN、Role ARN、または引き受けられたロールセッションが正確にどれであるかを教えてくれます。
aws sts get-caller-identity
期待される出力:
{
"UserId": "AIDAIAMUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/DevUser"
}
返されたARNが期待するユーザーまたはロールと一致しない場合、誤ったAWSプロファイルまたは環境変数の下で操作していることになります。
プロファイル設定とリージョンの確認
正しいAWSプロファイルが使用されていることを確認してください。これは--profileフラグで指定するか、AWS_PROFILE環境変数で設定できます。
# デフォルトプロファイルの設定を確認する
aws configure list
# または特定のプロファイルを確認する
aws configure list --profile prod-admin
出力にリージョンが表示されない、または不正確なリージョンが表示される場合、グローバルリソースまたはリージョン固有のサービス(S3バケットやEC2インスタンスなど)に対する操作が失敗する可能性があり、CLIが探している場所にリソースが見つからない場合は、Access Deniedとなることがあります。
ヒント:
sts get-caller-identityコマンド自体が認証エラーで失敗する場合、それはアクセスキーに根本的な問題があることを示しています(削除されている、取り消されている、または誤っている可能性があります)。
一時的な認証情報の扱い
IAMロール(STS AssumeRoleを介して)を使用している場合、CLIはSessionTokenを含む一時的な認証情報で動作します。これらの認証情報は(通常1時間後に)期限切れになります。AWS CLIは標準の認証情報プロバイダーチェーンから取得している場合は自動的に更新しますが、手動設定では失敗する可能性があります。
症状: コマンドは最初は機能しますが、一定期間(例:60分)経過後に認証エラーで失敗します。
解決策: カスタムスクリプトまたは手動でロードされた環境を使用している場合は、ロールを引き受ける方法に、認証情報の期限切れ時に更新するメカニズムが含まれていることを確認してください。
2. IAMポリシーと承認の詳細
使用されているIDを確認したら、次のステップはそのIDに必要な権限がない理由を特定することです。AWSの承認失敗は、複数のポリシーが同時に評価されるため、複雑です。
IAMポリシー評価の階層
承認エラーは通常、以下のポリシーコンポーネントのいずれかが原因で発生します。
- 明示的な拒否 (Explicit Deny): いずれかの適用可能なポリシー(IDベース、リソースベース、または境界)における明示的な
Denyステートメントは、常にAllowステートメントを上書きします。 - 許可の欠如 (Missing Allow): そのIDまたはリソースに適用されるポリシーが、特定の操作を許可していません。
A. IDベースのポリシー (ユーザーおよびロール)
ユーザーまたは引き受けられているロールに直接アタッチされているIAMポリシーを確認します。以下の点に注目してください。
- 必要なアクションの欠如 (Missing Actions): ポリシーに、必要なAPIアクション(例:
s3:ListBucket、ec2:DescribeInstances)が具体的にリストされていますか? - リソース制約 (Resource Constraints): ポリシーは
Resource要素を使用して、特定の操作を特定のリソースに制限していますか?一般的なエラーは、アクションが特定のARNを要求しているにもかかわらずResource: "*"を設定すること、またはその逆です。 - 条件 (Conditions): 満たされていない条件(例:ソースIPアドレス、時刻、MFAの要件)がありますか?
B. リソースベースのポリシー (S3, SQS, KMS)
S3やKMSのようなサービスでは、リソース自体が誰がアクセスできるかを規定するポリシーを持っています。IAMユーザーポリシーが明示的にアクセスを許可していても、リソースポリシーもユーザーがそのアクションを実行することを許可している必要があります。
例: 特定のVPCエンドポイント外のすべてのユーザーに対して明示的なDenyを持つS3バケット(リソースポリシー)にアクセスしようとすると、ユーザーのIAMポリシーに関わらずAccess Deniedとなります。
C. アクセス許可の境界とSCP
組織がAWS Organizationsを使用している場合、サービスコントロールポリシー (SCP) はアカウント内で許可される最大権限を定義します。同様に、アクセス許可の境界 (Permission Boundaries) はIAMエンティティが持つことができる最大権限を制限します。
SCPまたは境界が必要なアクションを拒否している場合、たとえIDベースのポリシーがその権限を付与していても、CLI操作は失敗します。
実用的なツール:IAMポリシーシミュレーター
複雑な失敗のトラブルシューティングを行う際、AWS Management ConsoleのIAMポリシーシミュレーターは非常に貴重です。特定のIAMエンティティに対して、特定の操作(例:s3:GetObject)を特定のリソース(例:arn:aws:s3:::my-bucket/key)に対してテストでき、どのポリシー文が拒否の原因であるかを正確に特定するのに役立ちます。
3. 一般的な「Access Denied」シナリオと解決策
シナリオ1:S3アクセス拒否 (リソース対ID)
S3のAccess Deniedは、ユーザーポリシーまたはバケットポリシーのいずれかから発生する可能性があるため、悪名高いです。
| 原因 | 診断 | 解決策 |
|---|---|---|
| バケットポリシーでの許可の欠如 | sts get-caller-identityは機能するが、aws s3 lsが失敗する。 |
バケットポリシーを修正し、呼び出し元のARNが必要なアクション(s3:ListBucket、s3:GetObject)を実行できるように明示的に許可する。 |
| KMS復号化権限の欠如 | 暗号化されたオブジェクトへのアクセスが失敗する(S3ポリシーが許可していても)。 | IAMエンティティが、オブジェクトを暗号化した基盤となるKMSキー(kms:Decrypt)を使用する権限を持っていることを確認する。 |
| リクエスター支払い | 大容量ファイルのダウンロード試行が失敗する。 | バケットがRequester Paysを要求する場合、CLIコマンドに--request-payer requesterフラグを含める必要がある。 |
シナリオ2:条件の失敗による暗黙的な拒否
多くのポリシーは、多要素認証(MFA)の要求など、セキュリティのベストプラクティスを強制する条件を利用しています。
ポリシーに次のような条件が含まれている場合:
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
そして、MFAで認証せずにコマンドを実行しようとすると、そのアクションは暗黙的に拒否されます。
解決策: MFAを必要とするコマンドの場合、まずMFAデバイスで認証されたSTSセッションを作成する必要があります。
# 1. MFAトークンを使用して一時的な認証情報を取得する
aws sts get-session-token --serial-number arn:aws:iam::123456:mfa/user --token-code 123456
# 2. 結果として得られるAccessKeyId、SecretAccessKey、およびSessionTokenをCLIセッションの環境変数としてエクスポートする。
シナリオ3:リージョンの欠如または不正確なリージョン
常にAccess Deniedエラーとなるわけではありませんが、正しいリージョンを指定せずにリソースに対してアクションを実行しようとすると、特にEC2、DynamoDB、EKSなどのリージョンサービスを操作する場合に、認証失敗やリソースが見つからないという失敗につながることがよくあります。
解決策: コマンドでリージョンを明示的に定義するか、プロファイルが正しく設定されていることを確認してください。
aws ec2 describe-instances --region us-west-2
4. 診断コマンドの概要
承認失敗の連鎖を迅速に診断するために、このコマンドチェックリストを使用してください。
| 目標 | コマンド | 目的 |
|---|---|---|
| IDの確認 | aws sts get-caller-identity |
コマンドを実行しているARNを確認します。 |
| 設定の確認 | aws configure list |
プロファイル設定、リージョン、出力形式を確認します。 |
| ポリシーの有効性テスト | (IAMポリシーシミュレーターを使用) | IAM IDが特定のリソースに対して特定のAPIアクションを実行できるかを確認します。 |
| ポリシーによる拒否の特定 | aws cloudtrail lookup-events ... |
CloudTrailを使用して、ポリシー評価が失敗した正確なイベントレコードを確認します。 |
結論:予防のためのベストプラクティス
AWS CLIでのAccess Deniedエラーを最小限に抑えるには、以下のセキュリティおよび運用のベストプラクティスを採用してください。
- 最小特権の使用 (Use Least Privilege): 絶対に必要な場合を除き、
*(ワイルドカード)アクセスを付与しないでください。ポリシーを必要なアクションとリソースに厳密に限定してください。 - IAMロールの使用 (Use IAM Roles): 特にスクリプトやCI/CDパイプラインでは、長期的なIAMユーザーキーを使用するよりもIAMロールを引き受けることを推奨します。これにより、認証情報が漏洩した場合の露出時間が制限されます。
- CloudTrailの監査 (Audit CloudTrail): 問題が解決しない場合、信頼できる情報源はAWS CloudTrailです。失敗したAPIコールのログイベントには、失敗の理由(例:
Policy Xによる拒否、MFAが必要)が含まれていることがよくあります。 - プロファイルの管理 (Manage Profiles): 異なるAWSアカウントやロールに対して個別のプロファイルを明確に命名し、管理してください(
--profile)。環境変数とプロファイル設定を混在させないでください。