AWS クロスアカウントアクセスと IAM ロール

AWSの同一アカウント/クロスアカウントにおけるポリシー評価、EC2インスタンスプロファイル、一時認証情報、IAMロールとS3バケットポリシーの連携をDVA向けに解説します。

学習順Step 4 / 101サービスIAM試験ドメインセキュリティ

AWS クロスアカウントアクセスと IAM ロール

複数のAWSアカウントを使うシステムでは、アプリケーションの実行主体が属するアカウントと、データを保管するリソースの所有アカウントが分かれることがあります。認可を考えるときは、「どの主体が要求を送るか」「どのアカウントがその主体を管理するか」「対象リソースの所有者は誰か」「どのポリシーが要求に適用されるか」を分けて追跡します。

とりわけ混同しやすいのは、ロールを引き受けるための許可と、引き受けたロールでAWS APIを実行する許可です。前者は信頼ポリシー、後者はロールの権限ポリシーが担当します。さらに別アカウントのリソースを操作するなら、リソース所有側のポリシーも要求を許可しなければなりません。

EC2のロールから別アカウントのS3へアクセスする際の認証情報とポリシー評価

アカウント境界とポリシー評価

クロスアカウント要求は両アカウントで許可される必要がある

クロスアカウントアクセスでは、要求元プリンシパルを管理するアカウントを信頼されるアカウント(trusted account)、アクセス対象リソースを所有し要求を受け入れる側を**信頼するアカウント(trusting account)**と呼びます。用語の向きは「誰が誰を信頼するか」を基準に読むと整理できます。

要求を許可するには、通常、次の両方がそろっていなければなりません。

  1. 要求元アカウント側:要求を行うIAMユーザーまたはロールに、対象リソースに対するアイデンティティベースポリシーの許可がある。
  2. リソース所有アカウント側:S3バケットポリシーなど対象リソースのリソースベースポリシーが、その要求元プリンシパルに対して操作を許可している。

したがって、クロスアカウント要求はアカウントごとの評価結果がともに Allow となる必要があり、論理的にはAND条件です。片側のポリシーに許可があっても、もう一方に許可がなければ十分ではありません。どちらかの評価に適用される明示的な Deny があれば、全体の最終結果は拒否です。AWS Organizations のサービスコントロールポリシー(SCP)、リソースコントロールポリシー(RCP)、権限境界など、許可の上限を定める仕組みが関与する場合も、追加の制限を満たす必要があります。

同一アカウントの許可は基本的に和集合

同一アカウント内のIAMユーザーまたはロールがリソースへアクセスする場合、アイデンティティベースポリシーとリソースベースポリシーによる許可は、基本的に**和集合(OR)**として扱われます。該当する操作がどちらかのポリシーで許可され、適用される明示的拒否がなく、ほかの制限も満たされれば、要求を許可できます。このため、通常、同じアカウントのIAMロールからS3バケットを使うだけなら、ロールのアイデンティティベースポリシーによる許可で足り、バケットポリシーが常に必須というわけではありません。

ただし「ORだからどんな場合も一方の許可だけで十分」と単純化してはいけません。権限境界やセッションポリシーなどの制限があれば実効権限は狭められます。また、リソースポリシーがIAMロールそのものではなくロールセッションARNを直接プリンシパルとして指定する場合、権限境界・セッションポリシーとの評価関係に特別な扱いがあるため、許可先がロールなのかロールセッションなのかを確認します。どのポリシーでも、該当する明示的 Deny は Allow に優先します。

観点 同一アカウント クロスアカウント
アイデンティティ側 アイデンティティベースポリシーによる許可が評価される 要求元アカウントで要求元主体のアイデンティティベース許可が必要
リソース側 リソースベース許可があれば、同一アカウント内の許可に加わる。常に必須ではない リソース所有アカウント側のリソースベース許可も必要
基本的な許可の結合 両種の許可は基本的に和集合 アカウントごとの許可結果がどちらもAllowとなる必要がある(AND)
明示的拒否 該当するDenyがAllowに優先 どちらのアカウント側であっても該当するDenyがあれば拒否

「クロスアカウントでは両方に許可を記述する」「同一アカウントではどちらか一方の許可で足りることがある」と対比すると、設問のポリシー不足を見つけやすくなります。一方、明示的拒否は単一アカウントでもクロスアカウントでも別格の優先順位を持ちます。

EC2アプリケーションにIAMロールを渡す

信頼ポリシーと権限ポリシーは役割が違う

IAMロールに関するポリシーは、少なくとも次の二つの問いに分けて読みます。

  • 信頼ポリシー:どのプリンシパルが、このロールの一時的な認証情報を取得するためにロールを引き受けられるか。
  • 権限ポリシー:ロールを引き受けたセッションが、どのAWSサービスのどのリソースに対して何を実行できるか。

信頼ポリシーはロールに付属するリソースベースポリシーです。EC2上で動くアプリケーションにロールを使わせる場合、EC2サービスプリンシパル ec2.amazonaws.com が sts:AssumeRole を行えるようにする信頼関係を設定します。EC2向けロールの作成ウィザードでは、ユースケースに応じた信頼設定が構成されます。

一方、S3への読み取りを許可するのは信頼ポリシーではなく、ロールにアタッチされた権限ポリシーです。信頼ポリシーだけ整えてもS3操作は認可されず、権限ポリシーだけ用意しても、そのロールを引き受ける主体が信頼されていなければ認証情報を取得できません。

インスタンスプロファイルと一時認証情報

EC2インスタンスとIAMロールは、インスタンスプロファイルを介して関連付けられます。インスタンスプロファイルにはロールが含まれ、EC2インスタンスからそのロールの一時認証情報を利用できるようにします。EC2向けインスタンスプロファイルには一つのIAMロールが関連付けられます。

インスタンス上のアプリケーションやAWS SDKは、インスタンスメタデータサービス(IMDS)を通じてロールの一時認証情報を取得します。AWS SDKやAWS CLIは通常、インスタンスプロファイルの認証情報を自動検出し、API要求に使います。認証情報は短期間で失効し、自動的に更新されるため、長期アクセスキーをインスタンスへ固定して配布・更新する必要を避けられます。実務ではIMDSv2の利用や、アプリケーションが取得した認証情報を外部へ漏えいさせないことも重要です。

EC2ロールのポリシー例

以下は、EC2サービスがロールを引き受けるための信頼ポリシー例です。アカウント番号やロール名は環境に合わせて設定してください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

次は、ロールの一時認証情報で、別アカウントが所有するS3バケット内の特定プレフィックスからオブジェクトを読み取るアイデンティティベース権限ポリシー例です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadCatalogExports",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::inventory-data-8472/catalog/*"
    }
  ]
}

s3:GetObject はオブジェクトARNを対象にする操作です。バケット内のオブジェクト一覧取得も必要なら、別のステートメントで s3:ListBucket をバケットARNに対して許可し、必要に応じて s3:prefix 条件を使って一覧範囲を制限します。バケットレベルとオブジェクトレベルの操作では、対象ARNの形式が異なる点に注意してください。

このロールの権限ポリシーが許可するのは要求元側の権限です。バケットを所有する別アカウントにも、そのロールからの要求を認める設定が必要です。

S3バケット側でクロスアカウントの主体を許可する

バケットポリシーはS3バケットに設定するリソースベースポリシーです。Principal に、アクセスを認めるIAMロールなどの主体を指定します。たとえば前述のEC2ロールを対象にし、特定のVPCエンドポイントを経由する要求だけに許可する例は次のとおりです。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCatalogReadsFromApplicationRole",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::246813579024:role/InventoryReaderOnEc2"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::inventory-data-8472/catalog/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceVpce": "vpce-07ab12cd34ef56a78"
        }
      }
    }
  ]
}

この例を有効にするには、アカウント番号・バケット名・ロール名・エンドポイントIDを実際の値に置き換えます。バケットポリシーの許可とEC2ロールの権限ポリシーの許可がそろい、条件にも一致した要求が、対象プレフィックスのオブジェクト読み取りに進めます。VPCエンドポイントポリシーも設定しているなら、それも要求を制限する追加の評価要素です。

条件付きAllowと明示的Denyを取り違えない

上記のバケットポリシーは、指定したロールが指定したVPCエンドポイントを経由する場合に Allow を与えます。そのポリシーだけがリソース側の該当許可であるクロスアカウントアクセスでは、条件を満たさない要求はリソース所有側の許可を得られず、結果として暗黙的に拒否されます。しかし、これは「そのバケットへの他の経路を明示的にすべて拒否する」ステートメントを置いたことと同じではありません。別のポリシーステートメントや別の設定が要求を許可し得る状況まで、一律に閉じる保証にはなりません。

特定のVPCエンドポイント以外からの要求を明示的に遮断したい設計では、aws:SourceVpce が指定値と一致しない場合に Deny するステートメントを検討します。明示的Denyは該当するAllowを上書きします。AWSの例で使われる StringNotEquals 条件は、指定したエンドポイントと一致しない場合にDenyを成立させます。条件キーが存在しないリクエストコンテキストを含むケースにも注意し、意図しないアクセス遮断を起こさないよう、AWSの条件評価仕様に沿って設計・検証してください。

VPCエンドポイントによる制限は通信経路の制御です。S3の公開エンドポイント自体を無効にする設定ではなく、バケットポリシーで要求元を評価します。エンドポイントを通らないコンソール操作や管理用アクセスも拒否対象になり得るため、管理者の復旧経路や運用手順を含めて確認します。誤ったエンドポイントIDでDenyを設定すると、正当なアクセスまで遮断される可能性があります。

クロスアカウントの要求を順に追う

アカウントAのEC2で稼働するカタログ処理が、アカウントBのS3バケットから商品情報を読むケースを考えます。要求の認証・認可は、次の順に整理できます。

  1. EC2インスタンスに割り当てられたインスタンスプロファイルを通じて、アプリケーションがIAMロールの一時認証情報を利用する。
  2. AWS SDKなどがその認証情報でS3 APIを呼び出す。ロールの信頼ポリシーは、EC2がロールを使用する関係を成立させる。
  3. アカウントA側で、ロールのアイデンティティベース権限ポリシーが、要求したS3アクションとオブジェクトARNを許可するか評価される。
  4. アカウントB側で、バケットポリシーがそのロールを Principal として認め、要求アクション・リソース・条件を許可するか評価される。
  5. 明示的Deny、権限境界、SCP/RCP、セッションポリシー、該当する場合はVPCエンドポイントポリシーなどの制限を確認し、全体として要求が許可されるか決まる。

ここで重要なのは、信頼ポリシーはS3アクセスを許可するポリシーではないことです。EC2からロールを利用できても、ロールの権限ポリシーまたはバケットポリシーが不足していれば、S3要求は失敗します。逆にS3側がロールを許可しても、呼び出し元のロール側に対象操作の許可がなければクロスアカウントの許可条件を満たしません。

大規模環境でポリシーを追跡する

単純な構成では、要求元に一つのアイデンティティポリシー、対象に一つのリソースポリシーを対応づけて調べられます。実環境では複数アカウント、ロール、バケット、条件、組織ポリシーなどが重なり、どの許可・制限が要求に適用されるかを追跡しにくくなります。

調査時には、少なくとも次の対応関係を一覧化します。

  • 要求を実行している実際のプリンシパル(IAMロール、ロールセッション、AWSサービスなど)
  • そのプリンシパルを所有するアカウントと対象リソースを所有するアカウント
  • アクション名と対象ARN。バケット操作かオブジェクト操作かも区別する
  • 呼び出し元ロールのアイデンティティポリシー、権限境界、セッションポリシー
  • バケットポリシーの Principal、Action、Resource、Condition および明示的Deny
  • OrganizationsのSCP/RCPやVPCエンドポイントポリシーなど、許可を制限する追加要素

「どのポリシーにもAllowがあるか」だけではなく、どのアカウントのどのポリシーが要求に適用されるかを特定すると、設定漏れや過剰許可を切り分けられます。

DVAでの判断ポイント

  • アカウントをまたぐかを先に判定する。クロスアカウントなら、要求元側のアイデンティティベース許可と、リソース所有側のリソースベース許可の両方を確認する。
  • 同一アカウントの評価は基本的にアイデンティティベース/リソースベース許可の和集合だが、暗黙のDeny、明示的Deny、権限境界、SCP/RCP、セッションポリシーなどを分けて考える。
  • 信頼ポリシーは「誰がロールを引き受けられるか」を定義する。権限ポリシーは「ロールを引き受けた後に何ができるか」を定義する。
  • EC2ではインスタンスプロファイルを介してロールを割り当てる。アプリケーションとAWS SDKは通常、IMDSから得られる自動更新される一時認証情報を利用する。
  • S3のバケットポリシーはリソース側から見た許可であり、別アカウントのロールを Principal に指定できる。
  • aws:SourceVpce を条件にしたAllowは条件一致時の許可であり、それだけで全経路を明示的に拒否するとは限らない。経路外を確実に拒否する要件では、明示的Denyの必要性と運用影響を検討する。
  • GetObject の対象はオブジェクトARN、ListBucket の対象はバケットARNであり、S3の操作に応じてリソース指定を合わせる。
  • AccessDenied の調査では、要求の実際のプリンシパル、両アカウントの許可、条件キー、明示的拒否、境界ポリシー、経路制限を順番に照合する。

公式ドキュメント

重要ポイント

  • ▸クロスアカウント要求は呼び出し元側のアイデンティティベース許可とリソース所有側のリソースベース許可の双方が必要で、どちらかの拒否で失敗する
  • ▸同一アカウントではアイデンティティベースとリソースベースの許可は基本的に和集合として評価されるが、権限境界などの上限やロールセッションへの直接許可に注意する
  • ▸IAMロールの信頼ポリシーはロールを引き受ける主体を定め、権限ポリシーは引き受けた後に実行できる操作を定める
  • ▸EC2ではインスタンスプロファイルを介してロールを関連付け、アプリケーションはメタデータサービスから自動更新される一時認証情報を利用する
  • ▸クロスアカウントのS3アクセスではロール側の許可とバケットポリシーの許可を照合し、必要ならVPCエンドポイント条件による経路制限も加える
  • ▸明示的DenyはAllowより優先される。条件付きAllowだけの場合は条件外リクエストに別のAllowがなければ暗黙的に拒否されるが、明示的Denyとは異なる

このトピックの学習を完了しますか?

完了状態はいつでも切り替えられます