IAM Access Analyzerの内部アクセス機能がSCP・RCP・Permission Boundaryの影響をどのように受けるか調査してみた

IAM Access Analyzerの内部アクセス機能がSCP・RCP・Permission Boundaryの影響をどのように受けるか調査してみた

IAM Access Analyzerの内部アクセス機能を使って、SCP・RCP・Permission Boundaryの制限が検知結果にどう影響するか実際に試してみました。意外な発見もありました、内部アクセスの運用を始める前にぜひ見てください。
Clock Icon2025.07.02

あしざわです。

先日のAWS re:Inforce 2025にて、IAM Access Analyzerの内部アクセス(Internal access)機能が発表されました。

https://dev.classmethod.jp/articles/iam-access-analyzer-internal-access-feature/

この機能によって、組織内の特定のリソースにアクセスできるすべてのIAMプリンシパルを特定し、内部ガバナンスをより強化できるようになりました。

そこで今回気になったのが、Organizations環境でよく利用される SCP(Service Control Policy)RCP(Resource Control Policy)Permission Boundary といったアクセス制限機能が、内部アクセス機能の検知結果にどのような影響を与えるのかという点です。

AWS公式ブログには以下のような表記がありました。

この機能は、自動推論を使用してサービスコントロールポリシー (SCP)、リソースコントロールポリシー (RCP)、アイデンティティベースのポリシーを含めた複数のポリシーをまとめて評価

評価対象にSCP、RCPが含まれていることは分かりましたが実際どのように検出するのかについてはこのブログからは読み取れませんでした。

この記事では、実際にOrganizations環境でSCP・RCP・Permission Boundaryを設定した状態で内部アクセス機能を使用し、検知結果がどのように表示されるかの検証内容をご紹介します。

「権限制限されているのに検知される」「制限が反映されない」といった運用上の疑問を解決できる内容になっているはずです。

概要

内部アクセス機能は、指定したリソース(S3バケット、RDS、DynamoDBなど)にアクセス可能なIAMプリンシパルをすべて特定する機能です。

これまでのIAM Access Analyzerは以下の2つの機能を提供していました。

  • 外部アクセス:信頼ゾーン外からのアクセスを検知
  • 未使用アクセス:IAMプリンシパルの使用状況を監視

内部アクセス機能の登場により、外部アクセス機能における信頼ゾーン内のIAMプリンシパルに対しても最小権限の原則を適用し、機微情報が保管されているリソースへのアクセス状況を把握できるようになりました。

一方で、Organizations環境では以下のようなアクセス制限機能がよく利用されています。

  • SCP(Service Control Policy):組織単位でのアクション制限
  • RCP(Resource Control Policy):リソース単位でのアクセス制限
  • Permission Boundary:IAMエンティティの権限上限設定

これらの制限が設定されている場合、内部アクセス機能の検知結果にどう反映されるのか、実際の権限評価と一致するのかが重要な検証ポイントとなります。

やってみた

この検証では、Organizationsを利用するため複数のアカウントが登場します。

全体の構成図はこちらです。

organizations-internal-access

簡単なテキストで表現すると以下のシナリオとなります。

  • 機密情報が入ったS3バケットを内部アクセスアナライザーで監視している
  • 検証用のIAMロールはS3FullAccess権限を付与
  • IAMロールに対して異なる制限機能を適用する
    • SCP :s3:DeleteObjectアクションを制限
    • RCP :メンバーアカウントA以外からのs3:PutObjectアクションを制限
    • Permission Boundary :s3:DeleteBucketアクションを制限
  • この状況下で内部アクセスはどのような検出結果を表示するのかを検証

ここから検証を進めます。

各アカウントには、事前に以下のリソースを準備しています。

メンバーアカウントA上のS3バケット

  • バケット名:internal-access-member-A-111111111111
  • バケットポリシー:internal-*と名前のつくIAMプリンシパルのみに以下アクションを許可
    • s3:GetObject
    • s3:DeleteBucket
    • s3:DeleteObject
    • s3:PutObject

メンバーアカウントB上のIAMロール

  • ロール名:internal-member-B-role
  • ポリシー:S3FullAccess
  • Permission Boundary:s3:DeleteBucketを制限

はじめに、SCPを作成しました。

CleanShot 2025-06-30 at 04.33.57

SCPをメンバーアカウントBにアタッチしました。

CleanShot 2025-06-30 at 04.34.48

次に、RCPを有効化します。

CleanShot 2025-06-30 at 04.36.22

RCPを作成する際、当初は以下のポリシーを設定しようとしました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyPutObjectFromNonMemberA",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::internal-access-member-a-*/*",
      "Condition": {
        "StringNotEquals": {
          "aws:PrincipalAccount": "<AWS_Account_ID>"
        }
      }
    }
  ]
}

しかし、ポリシードキュメント入力画面で以下のエラーが表示されました。

Rcp Missing Related Principal Condition Key: RCP は、IAM ロール、ユーザー、AWS サービスプリンシパルに影響を及ぼします。サービスプリンシパルを使用しユーザーに代わって動作するサービスへの意図しない影響を防ぐには、プリンシパルキー aws:PrincipalAccount が使用されるたびに、Condition ブロック "BoolIfExists": { "aws:PrincipalIsAWSService": "false"} にステートメントをさらに追加する必要があります。

提案されたaws:PrincipalIsAWSService句を追加することで警告が解消されました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyPutObjectFromNonMemberA",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::internal-access-member-a-*/*",
      "Condition": {
        "StringNotEquals": {
          "aws:PrincipalAccount": "<AWS_Account_ID>"
        },
        "BoolIfExists": {
          "aws:PrincipalIsAWSService": "false"
        }
      }
    }
  ]
}

RCPを作成し、メンバーアカウントAにアタッチしました。

CleanShot 2025-06-30 at 04.44.10

CleanShot 2025-06-30 at 04.45.39

制限機能の動作確認

準備が完了したので、IAMロールがS3バケットにアクセスできるかテストしました。

アカウントBにあるinternal-member-B-roleにスイッチし、AWS CLIのs3apiコマンドを利用してS3バケットポリシーで許可されているS3の各APIアクションを実行していきます。

私の想定は以下です

  • s3:GetObject:実行できる
  • s3:PutObject:失敗する(RCPの影響)
  • s3:DeleteObject:失敗する(SCPの影響)
  • s3:DeleteBucket:失敗する(Permission Boundaryの影響)

まず、s3:GetObject は問題なく実行できました。

> aws s3api get-object \
        --bucket internal-access-member-a-111111111111 \
        --key test-sensitive-data.html \
        ./test-sensitive-data.html
{
    "AcceptRanges": "bytes",
    "LastModified": "2025-06-29T19:24:07+00:00",
    "ContentLength": 131,
    "ETag": "\"bec32468316401e363d68abea22571a5\"",
    "ChecksumCRC32": "cxN1dA==",
    "ChecksumType": "FULL_OBJECT",
    "VersionId": "tr6a9W8gmyZkfh0e3IkxYfCwU8ezVWs9",
    "ContentType": "text/html",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}

> cat ./test-sensitive-data.html
<!DOCTYPE html>
<html>
<head>
    <title>Sensitive Data</title>
</head>
<body>
    <h1>This is sensitive data!</h1>
</body>
</html>

s3:PutObject は拒否されました。RCP(resource control policy)によって拒否されたとエラー文からわかります。

> aws s3api put-object \
        --bucket internal-access-member-a-111111111111 \
        --key test-upload.txt \
        --body ../test-file.txt

An error occurred (AccessDenied) when calling the PutObject operation: User: arn:aws:sts::961341544991:assumed-role/internal-member-B-role/test-session is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::internal-access-member-a-111111111111/test-upload.txt" with an explicit deny in a resource control policy

s3:DeleteObject も拒否されました。SCP(service control policy)によって拒否されたとエラー文からわかります。

> aws s3api delete-object \
        --bucket internal-access-member-a-111111111111 \
        --key test-sensitive-data.html

An error occurred (AccessDenied) when calling the DeleteObject operation: User: arn:aws:sts::961341544991:assumed-role/internal-member-B-role/test-session is not authorized to perform: s3:DeleteObject on resource: "arn:aws:s3:::internal-access-member-a-474668392285/test-sensitive-data.html" with an explicit deny in a service control policy

s3:DeleteBucket も拒否されました。Permission Boundaryによって拒否されたとエラー文からわかります。

> aws s3api delete-bucket \
        --bucket internal-access-member-a-111111111111

An error occurred (AccessDenied) when calling the DeleteBucket operation: User: arn:aws:sts::961341544991:assumed-role/internal-member-B-role/test-session is not authorized to perform: s3:DeleteBucket on resource: "arn:aws:s3:::internal-access-member-a-111111111111" with an explicit deny in a permissions boundary

想定通りに各制限機能が動作していることを確認できました。

続いて、管理アカウントにスイッチロールして、内部アクセスアナライザーを作成します。

信頼ゾーンはOrganizations全体、分析対象リソースは作成したS3バケット単体として設定しました。

CleanShot 2025-06-30 at 05.07.05

分析対象のリソースを指定する際は、以下の形式で入力する必要がありました。

<AWSアカウントID>,<S3バケットのリソースARN>

CleanShot 2025-06-30 at 05.06.35

AWSアカウントIDとARNのセットで入力しないとエラーになるので注意が必要です。

内部アクセスアナライザーを作成しました。

CleanShot 2025-06-30 at 05.17.54

しばらく待つと、18件の検知結果が表示されました。

CleanShot 2025-06-30 at 05.24.15

大半がS3バケットと同一のAWSアカウント上にある、広めのIAM権限を持つロール(Control Tower関連のロールが多数)でしたが、検証用に作成したIAMロールもしっかり検出されていました。

CleanShot 2025-06-30 at 05.34.14

詳細を確認してみます。

CleanShot 2025-06-30 at 05.31.25

検知結果から以下のことがわかりました。

  • このアクセス許可はバケットポリシーによって設定されている
  • SCP・RCPがAppliedのステータスになっている
  • Write権限とRead権限が含まれる3つのS3アクションでアクセス可能と表示されている

内部アクセス機能のAPIリファレンスによると、以下の4つの評価結果があります。

  • APPLIED:組織内にSCP/RCPが存在し、権限の評価にSCP/RCPが含まれた
  • APPLICABLE:組織内にSCP/RCPが存在するが、この評価結果にSCP/RCPが含まれない
  • NOT_APPLICABLE:組織内にSCP/RCPが存在しない
  • FAILED_TO_EVALUATE_[RCP/SCP]:SCP/RCPの評価中にエラーが発生した

Appliedと表示されているということは、SCP/RCPの影響で何らかの権限が制限されていることを示しています。

ここで重要な発見がありました。検出結果のAccess Levelを見ると、 Permission Boundaryによる制限は反映されているが、SCP・RCPの制限は反映されていない ということです。

実際のアクセステストでは以下の結果でした。

  • s3:GetObject:成功
  • s3:DeleteBucket:Permission Boundaryで拒否
  • s3:DeleteObject:SCPで拒否
  • s3:PutObject:RCPで拒否

しかし、内部アクセスの検知結果ではs3:GetObjects3:DeleteObjects3:PutObjectの3つのアクションでアクセス可能と表示されています。

つまり、内部アクセス機能とSCP・RCPを併用する場合、SCP・RCPで制限していても内部アクセスの存在が通知されてしまうため、適切なアーカイブルールの設定が重要になります。

続いて、SCP・RCPで制限している範囲をアーカイブルールで除外できるか試してみました。

Service control policy (SCP) restrictionをフィルタキーとして、適用済み(Applied)の値で検出結果をアーカイブする設定を作成しました。

CleanShot 2025-06-30 at 06.03.19

結果として、18件すべての検出結果がアーカイブされてしまいました。

CleanShot 2025-06-30 at 06.09.44

CleanShot 2025-06-30 at 06.09.57

当初は「ルールに一致したアクセス権限だけをアーカイブし、不一致なアクセス権限だけが検出結果として残る」という動作を期待していましたが、期待通りにはいきませんでした。

アーカイブルールを不適切に設定してしまうと、重要な検知を見逃す可能性があるため、運用上十分な注意が必要です。

さいごに

IAM Access Analyzerの内部アクセス機能とSCP・RCP・Permission Boundaryの関係について検証してみました。

今回の検証で明らかになった重要なポイントは以下の通りです。

まず、内部アクセス機能は Permission Boundaryによる制限は検知結果に反映する が、 SCP・RCPによる制限は検知結果に反映されない ということです。SCP・RCPが「Applied」ステータスで表示されていても、実際のアクセス権限の評価結果は検知結果に反映されません。

そのため、Organizations環境でSCP・RCPを活用している場合、内部アクセス機能による検知結果と実際のアクセス可能性にギャップが生じる可能性があります。

運用上の考慮事項として、SCP・RCPで制限されているアクセスについてはアーカイブルールで適切に除外する必要がありますが、今回の検証ではルール設定が思ったようにいかず、より詳細な検証が必要だと感じました。

内部アクセス機能は組織のガバナンス強化に非常に有用な機能ですが、既存のアクセス制限機能との関係を十分理解して運用することが重要ですね。

以上です。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.