AWS IAMを極める:アクセス拒否エラーの効果的なトラブルシューティング

CloudTrail、ポリシー評価ロジック、シミュレーター、SCP、境界、条件を使用してAWS IAMのAccessDeniedエラーをトラブルシューティングします。

AWS IAMを極める:Access Deniedエラーを効果的にトラブルシューティングする方法

AWS IAMのAccessDeniedエラーは、AWSがリクエストを評価した結果、有効な許可パスが見つからなかったことを意味します。最も迅速な修正方法は、より広範なポリシーを推測することではありません。AWSが評価した正確なアクション、リソース、プリンシパル、条件コンテキストを特定することです。

ほとんどのIAM障害は、次の4つのいずれかに起因します:一致するAllowがない、明示的なDenyがある、アクセス許可の境界やサービスコントロールポリシーがIDを制限している、またはリクエストと一致しない条件がある。

IAM評価ロジックから始める

AWSはデフォルトで拒否から始まります。リクエストが許可されるのは、該当するポリシーがそれを許可し、かつ該当するポリシーがそれを拒否しない場合のみです。

明示的なDenyはすべてのAllowよりも優先されます。その拒否は、IDポリシー、リソースポリシー、アクセス許可の境界、セッションポリシー、サービスコントロールポリシー、またはその他の該当するポリシータイプから発生する可能性があります。

同一アカウント内のアクセスの場合、IDポリシーとリソースポリシーが連携して機能することがよくあります。クロスアカウントアクセスの場合、通常は両側に権限が必要です:呼び出し元のIDがリクエストを行うことを許可され、かつターゲットリソースまたはターゲットアカウントがその呼び出し元を信頼または許可する必要があります。

失敗した正確なリクエストを取得する

ポリシーを編集する前に、以下の詳細を取得してください:

  • プリンシパル:ユーザー、ロール、引き受けたロールセッション、またはAWSサービスプリンシパル。
  • アクション:s3:GetObjectec2:RunInstancesなどのAPI操作。
  • リソース:ARNまたはリソースID。
  • リージョンとアカウント。
  • 条件:送信元IP、VPCエンドポイント、MFA、タグ、暗号化コンテキスト、またはリクエストされたリージョン。

CloudTrailが通常最良の情報源です。エラーが発生した時間帯の失敗イベントを検索し、eventNameuserIdentityresourceserrorCodeerrorMessageを確認します。

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances \
  --max-results 10

CloudTrailはすべての認可決定を完全に詳細に説明するわけではありませんが、不足しているアクションと実際のプリンシパルを提供することがよくあります。これだけで、引き受けたロールやセッション名の混同の多くを発見できます。

シミュレーションとアクセス分析ツールを使用する

IAMポリシーシミュレーターを使用すると、本番環境の権限を変更する前に、多くのIDベースのポリシーの問題をテストできます。ユーザーまたはロールを選択し、サービスアクションを選択し、可能な場合はリソースARNを指定し、関連する条件キーを含めます。

最近のAWSアカウントとサービスの場合は、アクセス拒否メッセージ自体も確認してください。一部のサービスは、エンコードされた認可失敗メッセージを返します。権限がある場合は、STSを使用してデコードします:

aws sts decode-authorization-message \
  --encoded-message '<encoded-message-from-error>'

デコードされたメッセージは、どのポリシータイプが拒否に寄与したかを示すことができます。

IAM Access Analyzerは、リソースポリシーやクロスアカウントの問題に役立ちます。意図しない外部アクセスを発見したり、デプロイ前に一部のポリシーを検証したりするのに役立ちます。

各ポリシーレイヤーを確認する

IDベースのポリシーは、ユーザー、グループ、ロールにアタッチされます。これらは、IDが何をできるかを定義します。

リソースベースのポリシーは、S3バケット、KMSキー、SQSキュー、Lambda関数、ロール信頼ポリシーなどのリソースにアタッチされます。これらは、誰がそのリソースを使用できるか、またはそのロールを引き受けられるかを定義します。

アクセス許可の境界は、ユーザーまたはロールの最大権限を設定します。これら自体はアクセスを許可しません。有効な権限は、IDポリシーと境界の共通部分です。

AWS Organizationsのサービスコントロールポリシーは、アカウントまたは組織単位の最大権限を設定します。SCPもそれ自体ではアクセスを許可しません。IAMポリシーが許可していても、アクションをブロックできます。

セッションポリシーと権限タグも、引き受けたロールセッションのアクセスを制限する可能性があります。あるパスでは機能するロールが、CIジョブによって引き受けられると失敗する場合は、セッションポリシー、セッションタグ、信頼ポリシーの条件を比較してください。

一般的なAccessDeniedパターン

依存アクションの欠落

一部のAWS操作には、明らかなアクション以上のものが必要です。たとえば、暗号化されたEC2インスタンスを起動するには、EC2権限に加えて、キーに対するKMS権限が必要になる場合があります。依存アクションについては、CloudTrailとサービスのドキュメントが最良の参考資料です。

誤ったリソースARN

S3のバケットレベルとオブジェクトレベルのARNは異なります:

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-bucket/*"
}

arn:aws:s3:::my-bucketはバケットをカバーします。arn:aws:s3:::my-bucket/*はバケット内のオブジェクトをカバーします。多くのS3エラーは、API呼び出しが他方を必要とするときに一方のみを許可することから発生します。

条件の不一致

条件はリクエストコンテキストと完全に一致する必要があります。特定のVPCエンドポイントからのみアクセスを許可するポリシーは、別のエンドポイント、パブリックAWSエンドポイント、または条件がそのリージョンをチェックしている場合は異なるリージョンからのリクエストを拒否します。

{
  "Effect": "Deny",
  "Action": "s3:*",
  "Resource": [
    "arn:aws:s3:::my-sensitive-data",
    "arn:aws:s3:::my-sensitive-data/*"
  ],
  "Condition": {
    "Bool": {
      "aws:SecureTransport": "false"
    }
  }
}

このステートメントはHTTPリクエストを拒否し、HTTPSリクエストはポリシー評価の残りの部分を続行できるようにします。これ自体はアクセスを許可しません。

KMSキーポリシーのギャップ

KMSは、混乱を招くアクセスエラーの一般的な原因です。IAMポリシーがkms:Decryptを許可している場合でも、キーポリシーはプリンシパルを直接許可するか、アカウントがIAMポリシーを通じてアクセスを委任することを許可する必要があります。

キーポリシー、権限付与、暗号化コンテキスト条件、およびキーを使用するサービスを確認してください。

実用的なトラブルシューティングフロー

まず、失敗した呼び出しを再現またはキャプチャします。CloudTrailから正確なAPIアクションとプリンシパルを取得します。

次に、SCP、リソースポリシー、アクセス許可の境界、IDポリシー内の明示的な拒否を検索します。明示的な拒否は他のすべてをオーバーライドするため、時間を節約できます。

次に、正確なアクションとリソースに対して一致する許可があることを確認します。KMSキー、サービスに渡されるIAMロール、ネットワークインターフェイス、ロググループなどの依存アクションと関連リソースを含めます。

最後に、可能な限り狭いポリシー変更でテストします。不明な拒否をAction: "*"Resource: "*"で修正することは避けてください。問題を隠し、新たなセキュリティリスクを生み出します。

有用な習慣は、すべてのAccessDeniedを証拠の問題として扱うことです。プリンシパル、アクション、リソース、ポリシーレイヤーがわかれば、修正は通常小さく明確です。