どーも!shihopowerです!
今回はクロスアカウントS3アクセスに必要な権限についてお話しします。
AWSのマルチアカウント構成を触っていると、「別アカウントのS3バケットにアクセスしたいのに、何をどこに設定すればいいんだっけ?」と混乱した経験はありませんか? バケットポリシー、KMSキー、IAMロール……設定箇所が複数あって、どれが何のためにあるのか整理しづらいですよね。
そこで今回は、AWS公式ドキュメントのみを参照しながら、クロスアカウントS3アクセスに必要な権限を1つひとつ丁寧に紐解いていきます。
忙しい人向け要約
- クロスアカウントアクセスの鉄則:ポリシーとロールはリソース側のアカウントで作成し、呼び出し元アカウントを信頼エンティティに指定する
- 呼び出し元アカウントのユーザー/ロールには
sts:AssumeRoleを許可するポリシーをアタッチする - クロスアカウントS3アクセスには 3つの設定 が必要
- ① S3バケットポリシー(リソース側でアクセス元のロールを許可)
- ② KMSキーの権限設定(暗号化データの復号化を許可)
- ③ QuickSight側のIAMサービスロール(サービスがロールを引き受けて動作)
- KMSの権限制御には キーポリシー・IAMポリシー・Grant の3種類がある
- KMS用IAMポリシーは アクセスする側(マーケティングアカウントのQuickSightロール) にアタッチする
- QuickSightに IAMユーザーではなくサービスロール を使う理由は、QuickSightがサービスプリンシパルとして動作し、長期認証情報を持つIAMユーザーが使えないから
目次
- 今回のシナリオ
- クロスアカウントアクセスの原理原則
- クロスアカウントS3アクセスに必要な3つの設定
-
KMSのアクセス制御:3つのメカニズム
4-1. KMSのIAMポリシーはどこにアタッチするか - なぜIAMユーザーではなくサービスロールなのか
- よくある落とし穴
- まとめ
1. 今回のシナリオ
以下のような構成を想定します。
- 営業アカウント(Account A):ペタバイト規模の営業データをS3バケットに保存。バケットはKMSキーで暗号化済み
- マーケティングアカウント(Account B):営業データをQuickSightで分析・可視化したい。QuickSight用のIAMサービスロールは作成済み
この2アカウント間で、最小の運用オーバーヘッドでS3バケットへ安全にアクセスするにはどうすればよいか、というのが今回のテーマです。
2. クロスアカウントアクセスの原理原則
個別の設定に入る前に、クロスアカウントアクセスを貫く原理原則を整理します。ここを理解していると、どのアカウントで何を作るべきか迷わなくなります。
鉄則:ポリシーとロールはリソース側のアカウントで作る
クロスアカウントアクセスの基本形は以下の3ステップです。
| ステップ | 作業内容 | 作業するアカウント |
|---|---|---|
| Step 1 | アクセス権限を定義したIAMポリシーを作成 | リソース側(データを持つ側) |
| Step 2 | IAMロールを作成し、Step 1のポリシーをアタッチ。呼び出し元アカウントを信頼エンティティに指定 | リソース側(データを持つ側) |
| Step 3 | ユーザー/ロールに sts:AssumeRole を許可するポリシーをアタッチ |
呼び出し元側(アクセスしたい側) |
今回のシナリオに当てはめると次のようになります。
【Step 1】 営業アカウント(リソース側)
S3読み取りを許可するIAMポリシーを作成
【Step 2】 営業アカウント(リソース側)
IAMロールを作成 → Step 1のポリシーをアタッチ
マーケティングアカウントを信頼エンティティに指定
【Step 3】 マーケティングアカウント(呼び出し元側)
QuickSightサービスロールに sts:AssumeRole を許可するポリシーをアタッチ
なぜリソース側でロールを作るのか
「呼び出し元(マーケティングアカウント)でロールを作ればいいのでは?」と思いがちですが、それでは本番アカウントのリソースを守れません。
ロールをリソース側で作成することで、「このロールを引き受けた人だけが、このS3バケットにアクセスできる」という制御をリソース所有者が握れます。呼び出し元アカウントのユーザーは、このロールを「借りる」だけであり、リソース側の管理者がいつでも権限を剥奪できます。
逆に呼び出し元でロールを作ってしまうと、リソース側から権限を制御する手段がなくなり、最小権限の原則に反してしまいます。
信頼エンティティとは
信頼エンティティとは「このロールを引き受けることを許可する相手」のことです。ロールの信頼ポリシー(Trust Policy)に記述します。
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<マーケティングアカウントID>:root"
},
"Action": "sts:AssumeRole"
}
この記述により、マーケティングアカウントのプリンシパルが sts:AssumeRole を使ってロールを引き受けられるようになります。
3. クロスアカウントS3アクセスに必要な3つの設定
結論として、以下の3つを組み合わせることで実現できます。
設定① S3バケットポリシー(営業アカウント側)
S3バケットポリシーは、バケット自体に設定するリソースベースのポリシーです。ここでマーケティングアカウントのQuickSightロールのARNをPrincipalとして指定することで、別アカウントからのアクセスを許可します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<マーケティングアカウントID>:role/<QuickSightロール名>"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<バケット名>",
"arn:aws:s3:::<バケット名>/*"
]
}
]
}
ポイント: バケットポリシーは「リソース側(営業アカウント)」からアクセスを許可する設定です。IAMポリシーだけでは別アカウントのバケットにはアクセスできません。
設定② KMSキーの権限設定(営業アカウント側)
S3バケットがKMSで暗号化されている場合、オブジェクトを読み取るには復号化の権限も別途必要です。バケットポリシーだけでは不十分で、KMSキーに対しても許可が必要です。
KMSの権限付与には**Grant(許可)**を使う方法が最もシンプルです。
aws kms create-grant \
--key-id <KMSキーのARN> \
--grantee-principal <QuickSightロールのARN> \
--operations Decrypt
Grantを使うメリットは、キーポリシー本体を変更せずに一時的な権限を付与・削除できる点です。詳細はセクション3で解説します。
設定③ QuickSightの権限設定(マーケティングアカウント側)
最後に、マーケティングアカウントのQuickSight側でも、対象のS3バケットへのアクセスを許可するよう設定を更新します。QuickSightのマネジメントコンソールから「Security & Permissions」→「Manage」→対象バケットを追加する形で設定できます。
3つの設定の関係性まとめ
【マーケティングアカウント (B)】 【営業アカウント (A)】
QuickSight S3バケット
↓ ロールを引き受ける ↑ ①バケットポリシーで許可
IAMサービスロール ─────────────────────→
─────────────────────→ KMSキー
↑ ②Grantで復号化を許可
③QuickSight側の
権限設定も更新
4. KMSのアクセス制御:3つのメカニズム
KMSキーへのアクセスを制御する方法はキーポリシー・IAMポリシー・Grantの3つです。それぞれの役割と違いを整理します。
キーポリシー(Key Policy)
すべてのKMSキーに必ず1つ存在するリソースベースのポリシーです。KMSアクセス制御の起点であり、キーポリシーが明示的に許可しない限り、IAMポリシーによるアクセスは効力を持ちません。
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<外部アカウントID>:root"
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "*"
}
IAMポリシー(IAM Policy)
キーポリシーでIAMポリシーが有効化されていることを前提に機能するアイデンティティベースのポリシーです。複数のKMSキーを一括管理したり、IAMグループに権限をまとめて付与したりしたい場合に特に有用です。
注意: キーポリシーとIAMポリシーは両方必要です。どちらか一方だけでは不十分です。
Grant(許可)
キーポリシーやIAMポリシーを変更せずに、プログラム的に一時的な権限を付与・削除できる仕組みです。AWSサービス(今回のQuickSightなど)がユーザーのデータを暗号化・復号化する際に自動的に使われることも多いです。
| キーポリシー | IAMポリシー | Grant | |
|---|---|---|---|
| 種別 | リソースベース | アイデンティティベース | 専用の権限機構 |
| 必須か | 必須(全キー) | 任意 | 任意 |
| Deny 可否 | ○ | ○ | ✕(許可のみ) |
| クロスアカウント | 単体で対応可 | キーポリシーとの併用必須 | 対応可 |
| 主な用途 | 基本的なアクセス制御 | 複数キー一括管理・委任 | 一時的・自動的な付与 |
4-1. KMSのIAMポリシーはどこにアタッチするか
「IAMポリシーをKMS用に作成する」と聞くと、どこにアタッチするのか迷いますよね。答えはシンプルです。
アタッチ先は、KMSキーにアクセスする側(呼び出し元)のIAMロールまたはIAMユーザーです。
今回のシナリオでは、マーケティングアカウントのQuickSight用IAMサービスロールにアタッチします。
クロスアカウントの場合、設定は2ステップに分かれます。
【Step 1】 営業アカウント (A) 側
KMSキーポリシーに外部アカウントへのアクセスを許可する記述を追加
【Step 2】 マーケティングアカウント (B) 側
QuickSightロールにIAMポリシーをアタッチし、
KMS操作(Decrypt等)を許可
IAMポリシーの例は以下のとおりです。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey*"
],
"Resource": "arn:aws:kms:<リージョン>:<営業アカウントID>:key/<キーID>"
}
}
ひとつ重要な点として、IAMポリシーにはキーポリシーと異なりPrincipal要素がありません。IAMポリシーはアイデンティティ(ロール等)にアタッチすることで初めて「誰に許可するか」が決まる仕組みのためです。
また、IAMグループはKMSキーポリシーのPrincipalに指定できないという制約があります。複数のユーザーやロールにKMSキーへのアクセスを許可したい場合は、キーポリシーのPrincipalにIAMロールを指定し、必要なユーザーがそのロールを引き受ける形が推奨されています。
| アタッチ先 | 設定するアカウント | |
|---|---|---|
| キーポリシー | KMSキー(リソース側) | 営業アカウント (A) |
| IAMポリシー | QuickSightロール(アクセス元) | マーケティングアカウント (B) |
| Grant | KMSキーに紐付け | 営業アカウント (A) から作成 |
5. なぜIAMユーザーではなくサービスロールなのか
QuickSight用の設定にIAMユーザーではなくIAMサービスロールを使う理由は、QuickSightが「人間」ではなく「AWSサービス」として動作するからです。
IAMロールはIAMユーザーと異なり、パスワードやアクセスキーのような長期的な認証情報を持ちません。ロールを引き受けた(AssumeRoleした)際に一時的なセキュリティ認証情報が発行されるため、認証情報の漏洩リスクを排除できます。
QuickSightの信頼ポリシーは以下のように設定します。
{
"Effect": "Allow",
"Principal": {
"Service": "quicksight.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
"Service": "quicksight.amazonaws.com" という記述が「このロールを引き受けられるのはQuickSightサービスだ」と宣言する部分です。これにより、QuickSightがS3やKMSに対して、このロールの権限で動作できるようになります。
| IAMユーザー | IAMサービスロール | |
|---|---|---|
| 紐付く対象 | 特定の人間 | AWSサービス(QuickSight等) |
| 認証情報 | 長期(アクセスキー等) | 一時的(AssumeRoleで発行) |
| QuickSightに使えるか | ✕ | ○(信頼ポリシーで許可) |
| セキュリティリスク | 認証情報漏洩の可能性 | 一時認証情報のため低リスク |
6. よくある落とし穴
クロスアカウントS3アクセスの設定でよく見かける誤ったアプローチとその問題点を整理します。
❌ 別アカウントにS3バケットを複製する(S3レプリケーション)
マーケティングアカウントに新しいS3バケットを作成し、営業アカウントのデータをレプリケーションで同期する方法です。一見シンプルに見えますが、ストレージコストが2倍になり、レプリケーション設定の管理も必要になります。既存のバケットを直接活用する設定と比べて、運用オーバーヘッドが大きくなります。
❌ SCPでアクセスを許可 + AWS RAMでKMSキーを共有する
SCP(Service Control Policy)はアカウントレベルのガードレールであり、アクセスを許可するためのものではありません。「許可しない操作を制限する」ものなので、クロスアカウントのアクセス許可には使えません。
またAWS RAM(Resource Access Manager)はVPCサブネットやRoute 53リゾルバーなどのリソースを共有するサービスであり、KMSキーの共有には対応していません。
❌ 営業アカウントにIAMロールを作り、それを引き受ける(ロールチェーン)
営業アカウントにIAMロールを作成し、マーケティングアカウントからそのロールをAssumeRoleしてS3にアクセスする方法です。S3アクセスの部分は実現できますが、KMSキーの復号化権限について設定が欠けています。KMSで暗号化されたオブジェクトを読み取るには、S3の権限だけでなくKMSのDecrypt権限も明示的に設定する必要があります。
7. まとめ
クロスアカウントS3アクセスに必要な権限を整理すると、以下の3点に集約されます。
- S3バケットポリシー:営業アカウントのバケットにマーケティングアカウントのQuickSightロールをPrincipalとして追加
-
KMSキーの権限設定:Grant(またはキーポリシー)でQuickSightロールに
Decryptを許可 - QuickSight側の設定:IAMサービスロールを使い、S3バケットへのアクセスをQuickSight管理画面から許可
「S3の権限を設定すれば終わり」ではなく、KMSの復号化権限も忘れずに設定する必要がある点が最大のポイントです。また、QuickSightのようなAWSサービスにはIAMユーザーではなくサービスロールを使う、という原則も押さえておくと、他のサービスでも応用が効きます。
この記事がどなたかの参考になれば幸いです。最後まで読んでいただきありがとうございました!