SJ blog
security
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

クロスアカウントIAMロール — 設計パターンと落とし穴

AWS複数アカウント構成でのIAMロール連携を解説。スイッチロール設定、External ID、ロールチェーン上限、OrganizationsとRAMを使った効率的な権限管理まで。

一言結論

クロスアカウントアクセスは信頼ポリシーとAssumeRole権限の双方向Allowが必須であり、外部ベンダーにロールを提供する場合はExternal IDでConfused Deputy攻撃を防ぐことが必須で、ロールチェーン時のセッション上限が1時間固定であることも設計時に考慮が必要だ。

クロスアカウントアクセスの基本構造

AWSマルチアカウント環境では「アカウントAのリソースをアカウントBから操作する」ケースが多い。これをIAMロールで安全に実現する仕組みを理解することはSAA・SCS両試験の必須知識だ。

アカウントA(委任元)              アカウントB(リソース所有)
┌─────────────────┐              ┌─────────────────────┐
│ IAMユーザー/ロール │ AssumeRole→ │ CrossAccountRole     │
│ (Principal)     │             │ (Trust Policy: A許可) │
└─────────────────┘              └─────────────────────┘

                                 アカウントBのS3/EC2等を操作

設定手順

ステップ1: アカウントB側でロールを作成(信頼ポリシー)

// アカウントBに作成するロールの信頼ポリシー
{
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::111111111111:root"
    },
    "Action": "sts:AssumeRole",
    "Condition": {
      "StringEquals": {
        "sts:ExternalId": "unique-external-id-xyz"
      },
      "Bool": {
        "aws:MultiFactorAuthPresent": "true"
      }
    }
  }]
}

arn:...:root は「アカウント111…内のIAM権限を持つ全エンティティ」を意味する。特定ユーザー/ロールに絞ることも可能。

ステップ2: アカウントA側でAssumeRole権限を付与

// アカウントAのユーザー/ロールに付与するポリシー
{
  "Statement": [{
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::222222222222:role/CrossAccountRole"
  }]
}

ステップ3: AssumeRoleを実行

# 一時クレデンシャル取得
aws sts assume-role \
  --role-arn arn:aws:iam::222222222222:role/CrossAccountRole \
  --role-session-name audit-session \
  --external-id unique-external-id-xyz \
  --duration-seconds 3600

# 結果の一時クレデンシャルを環境変数に設定
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...

External ID — Confused Deputy攻撃対策

External IDは「第三者がロールを不正に引き受ける(Confused Deputy問題)」を防ぐ仕組みだ。

シナリオ: SaaSベンダーXが複数顧客のAWSアカウントにアクセスするサービスを提供している。悪意のある顧客Bがベンダーのアカウント番号を使って顧客AのロールをAssumeRoleしようとする攻撃を防ぐ。

顧客ごとに異なるExternal IDを設定 → 顧客BはAのExternal IDを知らないので引き受けられない

ロールチェーンと最大セッション時間

ロールチェーン(RoleAがRoleBをAssumeRoleし、そのセッションからRoleCをAssumeRole)では重要な制限がある。

通常のAssumeRole: 最大12時間(ロール設定に依存)
ロールチェーン:   最大1時間(固定、変更不可)

STS AssumeRoleWithWebIdentity等のフェデレーション系も同様に1時間制限あり。

PassRoleとAssumeRoleの違い

iam:PassRole   : 「このロールをAWSサービスに渡す」権限
               例: EC2にIAMロールをアタッチする
               例: Lambda関数に実行ロールを設定する

sts:AssumeRole : 「このロールを自分が引き受ける」権限
               例: 別アカウントのロールで操作する
// Lambda実行ロールを設定できる権限
{
  "Effect": "Allow",
  "Action": "iam:PassRole",
  "Resource": "arn:aws:iam::*:role/LambdaExecutionRole*",
  "Condition": {
    "StringEquals": {
      "iam:PassedToService": "lambda.amazonaws.com"
    }
  }
}

マルチアカウント設計パターン

ハブアンドスポークモデル

管理アカウント(Hub)
    ├── 開発アカウント(Spoke)
    ├── ステージングアカウント(Spoke)
    └── 本番アカウント(Spoke)

→ 管理アカウントのIAMユーザーが各アカウントのロールをスイッチ

AWS SSOを使った集中管理

AWS IAM Identity Center(旧SSO)を使うと、ユーザーに複数アカウントへの一元的なアクセス管理が可能だ。個別にクロスアカウントロールを設定するより運用負荷が低い。

CloudTrailでのロール追跡

# 特定ロールのAssumeRole履歴を確認
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole \
  --query 'Events[?contains(CloudTrailEvent, `CrossAccountRole`)].{
    Time:EventTime,
    User:Username,
    SourceIP:CloudTrailEvent
  }'

CloudTrailでは sts:AssumeRole イベントに roleArnprincipalId(セッション名)が記録される。

試験対策チェックリスト

  • クロスアカウントは双方向Allow必須(信頼ポリシー+AssumeRole権限)
  • External IDは Confused Deputy 攻撃対策
  • ロールチェーン時の最大セッションは1時間固定
  • iam:PassRolests:AssumeRole は別の権限
  • Organizations使用時はSCPがクロスアカウントにも影響する