[アップデート] AWS のアクセス拒否メッセージにどのポリシータイプによる拒否なのかが含まれるようになりました(まだ一部サービス限定、追って追加対応予定!)

早めに犯人が特定されることで、Permissions boundary や Organizations SCP が恨まれる機会が減るのではないでしょうか。

うぅ……どのポリシーで弾かれているのか分からないよ……


コンバンハ、千葉(幸)です。

明示的な拒否ないしは暗黙的な拒否に悩まされている皆さん、朗報です。

一部の AWS サービスでアクセス拒否エラーのメッセージにどのポリシータイプが原因であるかが含まれるようになり、トラブルシュートが捗るようになりました。

論より証拠ということで例を引用すると以下の通りです。

Permissions_boundary_not_allow

AccessDeniedException

User: (プリンシパル名) is not authorized to perform: codebuild:ListProjects because no boundary policy allows the codebuild:ListProjects action

AdministratorAccess をアタッチしているのに何故と思ったら Permissions boundary、お前だったのか……! ということができるようになりました。

まだ対応しているのは一部の AWS サービスですが、数ヶ月以内には対応サービスが追加されていくとのことです!

IAM のポリシータイプは6個ある

今回のアップデートを理解する上で前提として外せないのは IAM のポリシータイプです。以下の 6 種が定義されています。

  • アイデンティティ(ID)ベースポリシー
  • リソースベースポリシー
  • アクセス許可の境界(Permissions boundary)
  • Organizations SCP
  • アクセスコントロールリスト
  • セッションポリシー

IAM でのポリシーとアクセス許可 - AWS Identity and Access Management

IAM の評価論理

AWS アクションを実行する際、上記で確認したようなポリシータイプがさまざま組み合わさり、最終的に「許可」「明示的な拒否」「暗黙的な拒否」の評価が得られます。

同一アカウントアクセスであれば、以下のようなフローで評価論理が表されます。(今回は詳細は覚えなくて大丈夫です。)

PolicyEvaluationHorizontal ポリシーの評価論理 - AWS Identity and Access Management より

余談ですがつい最近にこのフローチャートが更新されており、より複雑になっていました。(もちろん今回は覚えなくて大丈夫です。)

PolicyEvaluationHorizontal111621 Policy evaluation logic - AWS Identity and Access Management より

いわゆる IAM ポリシーであるアイデンティティベースポリシーは意識する機会が多いと思います。そこで許可を与えていたとしても、そのほかの Permissions boundary や Organizations SCP によって拒否されてしまう、ということは多々あります。

従来はどのポリシータイプによって拒否されているのかをエラーメッセージから確認することはできませんでしたが、今回のアップデートにより判別できるようになりました。改めて考えるとすごいですね。

どの AWS サービスが対応したのか

冒頭の記事から引用すると、対応サービスとして明記されているのは以下 3 つのサービスです。

  • Amazon Sagemaker
  • AWS CodeCommit
  • AWS Secrets Manager

……どういうチョイス???

かなりバラバラだなという印象ですが、ともかく上記のサービスが含まれていることは確実です。そしてこれら以外のサービスが現時点で対応していないかというと、そういうわけでもないようです。少なくとも AWS CodeBuild は対応していました。

Amazon Sagemaker, AWS CodeCommit and AWS Secrets Manager are among the first AWS services that now offer this additional context, with other services following in the next few months.

他のサービスは数ヶ月以内に続く、とあるので追加されていくのを期待して待っていましょう。

やってみた(CodeBuild)

以下のパターンでどういったメッセージが表示されるかを確認してみます。

# ID ベースポリシー アクセス許可の境界 評価結果
1 許可なし アタッチなし 暗黙的な拒否
2 拒否 アタッチなし 明示的な拒否
3 許可あり 許可なし 暗黙的な拒否
4 許可あり 拒否 明示的な拒否

マネジメントコンソールから CodeBuild のサービス画面を開くことで確認していきます。その操作により、裏側でcodebuild:ListProjectsアクションを実行することになります。

なぜ CodeBuild かと言うと、ただ単に CodeCommit と間違えたからです。

1. アイデンティティベースポリシーで暗黙的な拒否

以下の設定で臨みます。

  • ID ベースポリシー:アタッチなし
  • アクセス許可の境界:アタッチなし

アイデンティティベースポリシーについては、「ポリシーがアタッチされていないから許可がない」と「アタッチされているポリシーの中で許可がない」の違いはありません。( Permissions boundary では差異がある)

AccessDeniedException

User: (プリンシパル名) is not authorized to perform: codebuild:ListProjects because no identity-based policy allows the codebuild:ListProjects action

アイデンティティベースポリシーの中で許可がないためにアクセス拒否されている、というのがわかります。

2. アイデンティティベースポリシーで明示的な拒否

以下の設定で臨みます。

  • ID ベースポリシー:AWS 管理ポリシーAWSDenyAll
  • アクセス許可の境界:アタッチなし

AWSDenyAllはすべてのアクションを拒否するため、アタッチする対象は慎重に選択してください。(間違っても普段使用しているユーザーやロールにアタッチせず、検証用のものを使用してください。)

AccessDeniedException

User: (プリンシパル名) is not authorized to perform: codebuild:ListProjects with an explicit deny in an identity-based policy

アイデンティティベースポリシーによる明示的な拒否であることがわかります。

3. Permissions boundary による暗黙的な拒否

以下の設定で臨みます。

  • ID ベースポリシー:AWS 管理ポリシーAdministratorAccess
  • アクセス許可の境界:カスタムポリシー

カスタムポリシーの内訳は以下の通りです。NotActionで CodeBuild のアクションすべてを指定しています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "NotAction": "codebuild:*",
            "Resource": "*"
        }
    ]
}

AccessDeniedException

User: (プリンシパル名) is not authorized to perform: codebuild:ListProjects because no boundary policy allows the codebuild:ListProjects action

冒頭で引用したのがこの例です。

4. Permissions boundary による明示的な拒否

以下の設定で臨みます。

  • ID ベースポリシー:AWS 管理ポリシーAdministratorAccess
  • アクセス許可の境界:カスタムポリシー

カスタムポリシーの内訳は以下の通りです。上部のステートメントでAllowを与えておかないと、CodeBuild 以外のアクションに暗黙的な拒否を与えることになりますので注意してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": "codebuild:*",
            "Resource": "*"
        }
    ]
}

AccessDeniedException

User: (プリンシパル名) is not authorized to perform: codebuild:ListProjects with an explicit deny in a boundary policy

今更ですが Permissions boundary はboundary policyと表されることもあるんですね。

やってみた(Secrets Manager)

アイデンティティベースポリシーと Permissions boundary の例は確認できました。冒頭の記事では Organizations SCP の例が記載されているのでそちらも問題なく表示されるのだろうという想像がつきます。

ではリソースベースポリシーの場合はどうか?というのが気になったので、リソースベースポリシーが設定可能な Secrets Manager で確認してみます。

ちなみにどのサービスがリソースベースポリシーに対応しているかは以下ページから確認できます。

リソースベースポリシーによる明示的な拒否

以下のポリシーを シークレットにアタッチします。特定のプリンシパルからのアクセスを明示的に拒否しています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "*",
      "Effect": "Deny",
      "Resource": "arn:aws:secretsmanager:ap-northeast-1:000000000000:secret:test-secrets-lh10e3",
      "Principal": {
        "AWS": [
          "arn:aws:iam::000000000000:role/test-chiba-role"
        ]
      }
    }
  ]
}

この状態で、マネジメントコンソールから当該シークレットを参照します。

Secrets_Manager_Resourcebasepolicy

You don't have permission to describe secrets in Secrets Manager.

You don't have permission to view secret details. Contact your administrator to obtain DescribeSecret access.

どのポリシータイプによるものかが表示されていないですね……。

もしやと思い AWS CLI から試行してみました。

% aws secretsmanager describe-secret --secret-id test-secrets

An error occurred (AccessDeniedException) when calling the DescribeSecret operation: User: (プリンシパル名) is not authorized to perform: secretsmanager:DescribeSecret on resource: test-secrets with an explicit deny in a resource-based policy

with an explicit deny in a resource-based policyの記述があります。リソースベースポリシーが拒否の原因である場合も問題なく確認できそうです。

エラーメッセージでのポリシータイプの表示に対応しているサービスであっても、マネジメントコンソール上でそれが確認できるどうかはサービスによって異なりそうです。

アイデンティティベースポリシーで明示的な拒否

念のためリソースベースポリシー以外でも確認してみます。アイデンティティベースポリシーでsecretsmanager:*を Deny してマネジメントコンソールを開いてみます。

Secrets_Manager_Deny

You don't have permission to list secrets in Secrets Manager.

You don't have permission to view or select from existing secrets in your account. Contact your administrator to obtain ListSecrets access.

先ほどと同様、ポリシータイプは確認できません。

AWS CLI で同等のアクションを行います。

% aws secretsmanager list-secrets

An error occurred (AccessDeniedException) when calling the ListSecrets operation: User: (プリンシパル名) is not authorized to perform: secretsmanager:ListSecrets with an explicit deny in an identity-based policy

with an explicit deny in an identity-based policyの記述が確認できました。なるべくならマネジメントコンソール上でも同様の表示を行ってほしいですね。今後に期待です。

まとめ

  • 一部の AWS サービスでアクセス拒否エラーメッセージに拒否の原因であるポリシータイプが含まれるようになった
  • 初期から対応している AWS サービスの全体像は不明だが、以下は対応していることを確認できた
    • Amazon Sagemaker, AWS CodeCommit , AWS Secrets Manager , AWS CodeBuild
  • 対応している AWS サービスであっても、マネジメントコンソールから確認できるとは限らない
  • 今後の対応 AWS サービスは増えていく

IAM 評価論理トラブルシュートに役立つアツいアップデート

エラーメッセージにポリシータイプが含まれるようになる、というアップデートを確認しました。

さまざまなポリシータイプが絡むと途端に難しくなる IAM 評価論理ですが、エラー時にそのヒントを与えてくれるようになったので少しは付き合いやすくなったのではないでしょうか。

クロスアカウントの場合はどうなの?や VPC エンドポイントポリシーによる拒否の場合はどうなの?などまだ深掘りできていない部分があるので、情報が揃うのを待ちながら引き続きチェックしていこうかと思います。

以上、 チバユキ (@batchicchi) がお送りしました。