クロスアカウントアクセス入門：IAMロールのAssumeRoleを使いこなす

## 概要
複数のAWSアカウントを運用している場合、アカウント間のリソースアクセスが必要になることがあります。本記事では、IAMロールとAssumeRole機能を使用して、あるアカウントから別アカウントのリソースに安全にアクセスする方法を解説します。権限委譲の仕組みをヘルメットに例えて説明し、設定手順、トラブルシューティング、ベストプラクティスまで、実践的な知識を提供します。

## 目次
1. はじめに
2. IAMロールはヘルメット：アナロジーで理解するクロスアカウントアクセス
3. IAMロールとAssumeRoleの基本概念
4. 実装手順
   - 信頼ポリシーの設定
   - アクセス権限ポリシーの設定
   - AssumeRoleの実行
5. 実践的なユースケース
6. トラブルシューティング
7. セキュリティのベストプラクティス
8. 終わりに
9. 参考文献・参考サイト

## はじめに

AWSを本格的に活用している組織では、開発環境、テスト環境、本番環境など複数のAWSアカウントを管理していることが一般的です。こうした状況では、あるアカウントから別のアカウントのリソースにアクセスする必要が生じることがあります。例えば、本番環境のログを監視用アカウントから参照したり、共通のS3バケットに複数のアカウントからアクセスしたりするケースです。

「IAMロールのAssumeRole」は、このようなクロスアカウントアクセスを安全に実現するための重要な機能です。本記事では、この機能の仕組みと実装方法について、「ヘルメット」という例えを交えながら解説します。

## IAMロールはヘルメット：ヘルメットで理解するクロスアカウントアクセス

IAMロールを理解するために、「ヘルメット」という比喩がよく使われます。この例えを使って、クロスアカウントアクセスを説明しましょう。

### ヘルメットとしてのIAMロール

工事現場を想像してください。現場には「電気工事区域」「配管工事区域」「構造物区域」など、異なる作業エリア（AWSアカウント）があります。各エリアには、特定の作業をするための専用ヘルメット（IAMロール）が用意されています。

- 赤いヘルメット：電気工事の権限を持つ
- 青いヘルメット：配管工事の権限を持つ
- 黄色いヘルメット：構造物工事の権限を持つ

通常、あなた（ユーザー）は自分のエリア（アカウント）のヘルメットしか使えません。しかし、他のエリアで作業する必要が生じることがあります。

### AssumeRoleとは「ヘルメットを一時的に借りる」こと

あなたが電気工事エリア（アカウントA）の作業員ですが、配管工事エリア（アカウントB）で作業する必要が出てきました。この場合、次のようなプロセスが発生します：

1. 配管工事エリア（アカウントB）の管理者は、「訪問者用青いヘルメット」（クロスアカウントロール）を用意し、「電気工事エリアのこの作業員は借りてもよい」と設定します（信頼ポリシー）。
2. さらに、このヘルメットには「配管の点検はOK、しかし修理はNG」といった権限が設定されています（アクセス権限ポリシー）。
3. あなたは自分のID（アカウントAの認証情報）を示して、「訪問者用青いヘルメット」を一時的に借ります（AssumeRole）。
4. 安全管理室（AWS STS）は、あなたの身分を確認し、期限付きの「訪問者証」（一時的認証情報）を発行します。
5. あなたは青いヘルメットと訪問者証を持って、配管工事エリアで許可された作業を行います。
6. 作業が終わったら（または時間が経過したら）、ヘルメットと訪問者証は無効になります。

![Screenshot_20250519-082559~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4071751/91c70bd8-697e-4add-8af3-7ab42102bfca.png)


AWSの公式ドキュメントでも、IAMロールはある種の「ヘルメット」として説明されることがあります。特定の権限を持つヘルメットを被ることで、一時的にその権限を行使できる仕組みです。

![Screenshot_20250519-082454~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4071751/1ca964bc-3d15-475f-a6a0-d213f9842936.png)


## IAMロールとAssumeRoleの基本概念

### IAMロール（ヘルメット）とは
IAMロールは、特定のアクセス許可を持つエンティティです。ユーザーやAWSサービスがこのロール（ヘルメット）を一時的に「被る（assume）」ことで、ロールに紐づけられた権限を使用できるようになります。

ヘルメットの例えで言えば：
- ヘルメットは人（ユーザー）から独立して存在する
- ヘルメットには特定の権限（色や記章など）がある
- 誰でも被れるわけではなく、被る資格がある人のみが使える
- ヘルメットを被っている間だけ、その権限が有効になる

### AssumeRole（ヘルメットを被る）とは
AssumeRoleは、AWS Security Token Service (STS) の操作の一つで、指定したロール（ヘルメット）を一時的に被るための認証を行います。

AWSの公式ドキュメントでは、AssumeRoleを次のように定義しています：

> AssumeRole オペレーションは、他のAWSアカウントのIAMロールを一時的に引き受けるために使用され、権限委任のメカニズムを提供します。

https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html より引用

### 権限委譲の流れ（ヘルメット貸出システム）

権限委譲の流れをヘルメットのアナロジーで表すと：

1. アカウントB（配管工事エリア）で特別なヘルメットを作成し、「アカウントAのこの人は借りてよい」と登録する
2. アカウントA（電気工事エリア）のユーザーが「ヘルメットを貸してください」と安全管理室（STS）に申請する
3. 安全管理室が身分確認をし、期限付きの訪問証明書（一時認証情報）を発行する
4. ユーザーはヘルメットと証明書を持って、アカウントBのリソースにアクセスする

![Screenshot_20250519-082654~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4071751/1e268a3e-8462-4d6e-9f24-0ad336d071eb.png)


## 実装手順

それでは実際に、アカウントAからアカウントBのS3バケットにアクセスするための設定手順を見ていきましょう。

![Screenshot_20250519-082800~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4071751/816fb66c-32be-4a0d-a429-a0a456030130.png)


### 1. 信頼ポリシーの設定（アカウントB側：ヘルメットを誰に貸すか決める）

アカウントBで、アカウントAのユーザーが被ることができるIAMロール（ヘルメット）を作成します。重要なのは「信頼ポリシー」の設定です。これは「このヘルメットを誰が借りられるか」を定義します。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT-A-ID:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
```

ここで `ACCOUNT-A-ID` はアカウントAのAWSアカウントIDに置き換えてください。

より制限的な設定として、特定のユーザーやロールのみにAssumeRoleを許可することもできます：

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT-A-ID:user/specific-user"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
```

### 2. アクセス権限ポリシーの設定（アカウントB側：ヘルメットでできることを決める）

次に、作成したロール（ヘルメット）にどのような権限を与えるかを定義するポリシーを設定します。これは「このヘルメットを被ったらどんな作業ができるか」を決めます。例えば、特定のS3バケットへの読み取りアクセスを許可する場合：

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::example-bucket",
        "arn:aws:s3:::example-bucket/*"
      ]
    }
  ]
}
```

### 3. AssumeRoleの実行（アカウントA側：ヘルメットを借りる）

アカウントAのユーザーが、アカウントBのロール（ヘルメット）を被るには、AWS CLI、SDK、またはコンソールを使用します。

AWS CLIを使用した例：

```bash
aws sts assume-role \
  --role-arn "arn:aws:iam::ACCOUNT-B-ID:role/CrossAccountRole" \
  --role-session-name "CrossAccountSession"
```

このコマンドは、一時的な認証情報（訪問者証明書）を返します：

```json
{
  "Credentials": {
    "AccessKeyId": "ASIA...",
    "SecretAccessKey": "wJalr...",
    "SessionToken": "AQoD...",
    "Expiration": "2023-12-15T00:00:00Z"
  },
  "AssumedRoleUser": {
    "AssumedRoleId": "AROA...:CrossAccountSession",
    "Arn": "arn:aws:sts::ACCOUNT-B-ID:assumed-role/CrossAccountRole/CrossAccountSession"
  }
}
```

これらの認証情報を使用して、アカウントBのリソースにアクセスできます。これは「ヘルメットを被って、訪問者証明書を携帯して作業する」イメージです。

AWS CLIでは、プロファイルとして設定することで簡単に切り替えることができます（あらかじめヘルメットを準備しておく感じ）：

```bash
# ~/.aws/config に以下を追加
[profile cross-account]
role_arn = arn:aws:iam::ACCOUNT-B-ID:role/CrossAccountRole
source_profile = default
```

これにより、以下のようにプロファイルを指定するだけでAssumeRoleが行われます（簡単にヘルメットを被れる）：

```bash
aws s3 ls s3://example-bucket --profile cross-account
```


## 実践的なユースケース

AssumeRole（ヘルメットの貸し借り）を活用した実践的なユースケースをいくつか紹介します：

### 1. 中央管理アカウントからの複数環境の監視（巡回警備）

開発、テスト、本番の各環境を別アカウントで管理している場合、中央の監視アカウントから各環境用のヘルメット（監視用ロール）を被り、すべての環境のCloudWatch LogsやCloudTrailログにアクセスする。まるで各現場を巡回する警備員のようです。

### 2. デプロイパイプラインの自動化（配送業者）

CICDパイプラインが動作する開発アカウントから、本番アカウントへのデプロイを自動化する。これは、配送業者（デプロイシステム）が異なる建物（アカウント）に荷物を届けるために、その建物専用のヘルメットを一時的に被るようなものです。

### 3. 共有リソースへのアクセス（共用施設管理）

複数のアカウントで共有されるS3バケットやDynamoDBテーブルなどの共通リソースへのアクセス管理。これは、複数の部署が利用する共用設備に対して、各部署の従業員が「共用設備管理用ヘルメット」を一時的に被って作業するようなものです。

### 4. 緊急時のアクセス（緊急対応）

通常は制限されている本番環境へ、緊急時に限定的なアクセスを提供する「ブレークグラス」メカニズム。これは、災害時などに「緊急対応用ヘルメット」を使って普段は立ち入れないエリアに入るようなものです。

## トラブルシューティング

AssumeRole（ヘルメットの貸し借り）を使用する際によくある問題とその解決方法を紹介します：

| 問題 | ヘルメットの例え | 考えられる原因 | 解決策 |
|------|----------------|--------------|-------|
| `AccessDenied` エラー | 「このヘルメットは借りられません」 | 信頼ポリシーが正しく設定されていない | 信頼ポリシーのPrincipalが正しいか確認 |
| `ExpiredToken` エラー | 「訪問者証明書の有効期限が切れています」 | 一時認証情報の有効期限切れ | 再度AssumeRoleを実行して新しい認証情報を取得 |
| 権限不足エラー | 「このヘルメットではその作業はできません」 | ロールに必要な権限がない | アクセス権限ポリシーを見直す |
| MFAが必要というエラー | 「ヘルメットを借りるには追加の身分証明が必要です」 | ロールがMFAを要求している | `--serial-number`と`--token-code`オプションを追加 |

AWSの公式ドキュメントにあるように、IAMアクセスアナライザーを使用すると、クロスアカウントアクセスの問題を特定するのに役立ちます：

https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-resources.html を参照

## セキュリティのベストプラクティス

クロスアカウントアクセス（ヘルメットの貸し借り）を安全に実装するためのベストプラクティスを紹介します：

1. **最小権限の原則の適用**：必要最小限の権限のみを付与する
   （ヘルメットの例え：ヘルメットに「必要な作業のみできる」権限を設定）

2. **一時的な認証情報の有効期限を短く設定**：デフォルトは1時間、最大は12時間
   （ヘルメットの例え：訪問者証明書の有効期限を短く設定）
   ```bash
   aws sts assume-role \
     --role-arn "arn:aws:iam::ACCOUNT-B-ID:role/CrossAccountRole" \
     --role-session-name "CrossAccountSession" \
     --duration-seconds 3600
   ```

3. **条件付き信頼ポリシーの使用**：特定のIPアドレス範囲や時間帯のみアクセスを許可
   （ヘルメットの例え：「特定のゲートから入場した人だけ」「営業時間内だけ」ヘルメットを貸し出す）
   ```json
   "Condition": {
     "IpAddress": {
       "aws:SourceIp": "192.0.2.0/24"
     }
   }
   ```

4. **AWS Organizations SCP（サービスコントロールポリシー）の活用**：組織レベルでの権限境界を設定
   （ヘルメットの例え：組織全体での安全規則を設定）

5. **MFA認証の要求**：機密性の高いリソースアクセスにはMFAを必須にする
   （ヘルメットの例え：重要エリア用のヘルメットを借りるには、通常のIDに加えて追加の身分証明が必要）
   ```json
   "Condition": {
     "Bool": {
       "aws:MultiFactorAuthPresent": "true"
     }
   }
   ```

6. **CloudTrailによる監査**：クロスアカウントアクティビティを監視・記録する
   （ヘルメットの例え：誰がいつどのヘルメットを借りて、どの作業をしたかを記録する）

AWSの公式セキュリティブログでは、クロスアカウントアクセスのベストプラクティスについて詳しく解説しています：

https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/ を参照

## 終わりに

本記事では、IAMロールとAssumeRoleを「ヘルメット」の比喩を使って解説し、クロスアカウントアクセスの基本概念、実装方法、ユースケース、トラブルシューティング、セキュリティのベストプラクティスについて紹介しました。

複数のAWSアカウントを運用する際は、適切なクロスアカウントアクセス管理が重要です。ヘルメット（IAMロール）の貸し借りシステムを活用することで、長期的な認証情報の共有を避け、より安全かつ監査可能な方法でアカウント間のリソースアクセスを実現できます。

次のステップとして、AWS Organizationsと組み合わせた大規模な環境でのアクセス管理や、IAM Identity Centerを使用した統合認証についても学んでみることをおすすめします。

皆さんのAWS環境でのセキュリティと利便性の両立にお役立ていただければ幸いです。

## 参考文献・参考サイト

- [IAM ユーザーガイド - ロールを使用したアカウント間のアクセス委任](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html)
- [AWS STS APIリファレンス - AssumeRole](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html)
- [AWS CLI コマンドリファレンス - sts assume-role](https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role.html)
- [IAMロールとAssumeRoleの使い方](https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/)
- [AWS Security Blog - IAM ロールの信頼ポリシーの使用方法](https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/)
- [IAM Access Analyzer ユーザーガイド](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-resources.html)