AssumeRoleとPassRoleでAWSサービスが別のリソースにアクセスするフローを整理した
はじめに
この記事は主にAWSのIAM User Guideなどを参考に、AWS上でサービスからリソースへのアクセスがどのように行われるかをまとめたものです。実際の環境構築の手順や設定よりも、サービス、リソース間のアクセスの仕組みを理解することに重点を置いています。
前提知識
本題に入る前に、知っておくべき基本的な知識を挙げます。
ポリシーの構成要素
AWS上での主体となるIAMユーザーやIAMロールは、割り当てられたポリシーによって何ができるか(またはできないか)が決まります。また、アクセスされる側のリソースに対しても、誰がアクセスして良いかを決定できます。ほとんどのポリシーはJSON形式でAWSに保存されています。ポリシーは複数の要素で構成されますが、特に重要な要素を以下に示します。
要素 | 説明 |
---|---|
Effect |
アクションを許可または拒否する。Allow(許可)またはDeny(拒否)のいずれかが指定される。 |
Principal |
AWSリソースにアクセスする主体。IAMユーザーやIAMロール、AWSサービスなどが指定できる。 |
Resource |
アクセス先のリソースを指定する。 |
Action |
許可または拒否されるアクションを指定する。 |
ざっくりした視点だとポリシーによって、
- 誰が(
Principal
)、何に対して(Resource
)、何ができる(Effect: Allow
とAction
) - 誰が(
Principal
)、何に対して(Resource
)、何ができない(Effect: Deny
とAction
)
上記のいずれかを決めたり、それぞれを複数組み合わせたりできると認識して良いかと思います。
アイデンティティーベースとリソースベースのポリシー
ポリシーには「アイデンティティーベースのポリシー」と「リソースベースのポリシー」があります。後述する信頼ポリシーはリソースベースのポリシーに分類されるため、両者の区別は重要です。
アイデンティティーベースのポリシー
IAMユーザーやIAMロール、AWSサービスなどのアクションを行う主体に対して割り当てるポリシーです。リソース自身が暗黙的にPrincipal
となるため、アイデンティティーベースのポリシーにはJSONの中でPrincipal
を指定することはできません。
リソースベースのポリシー
アクションが行われる側のリソースに対して割り当てるポリシーです。誰がリソースにアクセスできるかを指定できます。JSON中のPrincipal
を指定する必要があります。
サービスロールとは
IAMロールの一種で、AWSサービスが引き受けるロールです。ユーザーの代わりにサービスがロールに定義された権限を持ってアクションを実行できます。
概要
本題に入ります。IAMロールを使用してAWSサービスが別リソースにアクセスする際の概念的なフローを以下にまとめました。具体的に想像しやすくなるように、アクセスするサービスをAWS Lambda、アクセスされるリソースをAmazon DynamoDBとして説明しますが、他のサービスに置き換えても問題ありません。
今回登場してくる各AWSのリソースとその役割を簡潔に挙げます。
リソース | 役割 |
---|---|
AWS Lambda | 別のリソースにアクセスしようとしているサービス。 |
Amazon DynamoDB | アクセスされるリソース。 |
AWS STS | 一時的な認証情報を提供するサービス。この認証情報によってAWSサービスがIAMロールを引き受けることができる。 |
IAMロール | AWSサービスが引き受けるIAM ロール。他のリソースに対してアクセスする権限を持っている。 |
管理者 | IAMロールを管理するユーザー。 |
開発者 | AWSサービスへIAMロールの委譲を許可するユーザー。 |
ここに出てくるIAMロールは、Lambdaが他のサービスやリソースにアクセスするのを許可するためのもので、実行ロールと呼ばれます。
また、実行ロールはLambdaがサポートしているサービスロールです。[1]
個々のフローについて
全体のフローはAWS内の複数のエンティティやサービスの相互作用が組み合わさって成り立っています。
その中で今回重要になる3つのIAMの認可に関する設定について説明します。
IAMロールを作成し、ポリシーを割り当てる
1つ目は、ユーザーがIAMロールを作成し、そのロールに適切な権限を割り当てる設定です。このロールの権限で許可されているアクションを引き受けたサービスが実行できるようになります。
アクセスマネジメントの設定
この記事では、サービスが引き受けるIAMロールの作成とポリシーの設定は管理者が行う前提としています。管理者は最低限、以下の権限を持っていれば問題ありません。
権限要素 | 内容 |
---|---|
誰が | 管理者(自分) |
何に対して | IAMロール |
何ができる | 作成、ポリシーの設定 |
また、作成したIAMロールに対して、別リソースにアクセスするための権限を設定します。このロールをAWS Lambdaが引き受けることで、Amazon DynamoDBにアクセスできるようになります。ここでは、Amazon DynamoDBに対して読み取りと書き込みの操作が必要であると想定しています。
権限要素 | 内容 |
---|---|
誰が | IAMロール(自分) |
何に対して | Amazon DynamoDB |
何ができる | 読み取り、書き込み |
IAMロールを引き受けることを許可する
2つ目は、ユーザーがサービスにIAMロールの権限を渡すフローです。この際、ポリシーのActionとしてiam:PassRole
を指定します。他リソースにアクセスするサービスを利用する上で、ユーザーがIAMロールを渡す権限の設定が必要です。具体的な例であれば、ユーザーがLambdaの関数を作成しようとする際に CreateFunction API を呼び出すと、以下の2つの権限がチェックされます。
- CreateFunction APIの権限を持っているか
- IAMロールを渡す権限を持っているか
この2つのうち、いずれかひとつでも持っていない場合、操作は失敗します。[2]
サービスやアプリケーションが持つ権限と、そのサービスを使用しているユーザーが持つ権限が異なる場合がありますが、iam:PassRole
によりユーザーが適切にサービスにIAMロールを渡すことができます。iam:PassRole
でサービスにロールを渡すとき、ユーザーが持っている以上の権限をサービスが持たないように注意する必要があります。
アクセスマネジメントの設定
Lambdaを操作するユーザーを「開発者」として設定する場合、開発者にはiam:PassRole
とLambda関数に関する操作権限を割り当てます。
権限要素 | 内容 |
---|---|
誰が | 開発者(自分) |
何に対して | IAMロール |
何ができる | 権限を委譲する |
権限要素 | 内容 |
---|---|
誰が | 開発者(自分) |
何に対して | AWS Lambda |
何ができる | 必要な操作 |
サービスがIAMロールを引き受ける
最後は、AWSサービス、AWS STS、IAMロール間でのやり取りです。サービスがIAMロールを引き受けるために、一時的な認証情報を取得するフローです。この際、ポリシーのActionとしてsts:AssumeRole
を指定します。
IAMロールはIAMユーザーと異なり、一時的な認証情報を持ちます。AWS Security Token Service (AWS STS) がIAMロールのための認証情報を作成します。サービスは sts:AssumeRole
アクションをIAMロールに対して実行することで、AWS STSからロールの認証情報を受け取り、その後のAWS内でのリクエストにその情報を含めて送信します。これにより、サービスがIAMロールを引き受けることができます。
アクセスマネジメントの設定
サービスがIAMロールを引き受ける際には、アクセスされる側のIAMロールに対してリソースベースのポリシーを割り当てます。
権限要素 | 内容 |
---|---|
誰が | AWS Lambda |
何に対して | IAMロール(自分) |
何ができる | ロールを引き受ける |
この AssumeRole が行われるIAMロールに割り当てるリソースベースのポリシーを「信頼ポリシー」といいます。
まとめ
各フローの説明は以上になります。AWSでのサービスやリソース間のアクセスが可能になるためには、次のことが行われている必要があります。
- サービスが使用するIAMロールを作成し、別リソースにアクセスするための権限を設定する
- IAMロールを引き受けることを許可する
- サービスがIAMロールを引き受ける
AWSで環境構築する際、これらの認可設定は頻繁に見るので、単に手順を踏むだけでなく、全体の仕組みを理解してから作業することが効果的なのではないかと思っています。
Discussion