🏙️

AssumeRoleとPassRoleでAWSサービスが別のリソースにアクセスするフローを整理した

2024/08/14に公開

はじめに

この記事は主にAWSのIAM User Guideなどを参考に、AWS上でサービスからリソースへのアクセスがどのように行われるかをまとめたものです。実際の環境構築の手順や設定よりも、サービス、リソース間のアクセスの仕組みを理解することに重点を置いています。

前提知識

本題に入る前に、知っておくべき基本的な知識を挙げます。

ポリシーの構成要素

AWS上での主体となるIAMユーザーやIAMロールは、割り当てられたポリシーによって何ができるか(またはできないか)が決まります。また、アクセスされる側のリソースに対しても、誰がアクセスして良いかを決定できます。ほとんどのポリシーはJSON形式でAWSに保存されています。ポリシーは複数の要素で構成されますが、特に重要な要素を以下に示します。

要素 説明
Effect アクションを許可または拒否する。Allow(許可)またはDeny(拒否)のいずれかが指定される。
Principal AWSリソースにアクセスする主体。IAMユーザーやIAMロール、AWSサービスなどが指定できる。
Resource アクセス先のリソースを指定する。
Action 許可または拒否されるアクションを指定する。

ざっくりした視点だとポリシーによって、

  • 誰が(Principal)、何に対して(Resource)、何ができる(Effect: AllowAction
  • 誰が(Principal)、何に対して(Resource)、何ができない(Effect: DenyAction

上記のいずれかを決めたり、それぞれを複数組み合わせたりできると認識して良いかと思います。

アイデンティティーベースとリソースベースのポリシー

ポリシーには「アイデンティティーベースのポリシー」と「リソースベースのポリシー」があります。後述する信頼ポリシーはリソースベースのポリシーに分類されるため、両者の区別は重要です。

アイデンティティーベースのポリシー

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で環境構築する際、これらの認可設定は頻繁に見るので、単に手順を踏むだけでなく、全体の仕組みを理解してから作業することが効果的なのではないかと思っています。

脚注
  1. https://docs.aws.amazon.com/lambda/latest/dg/security_iam_service-with-iam.html#security_iam_service-with-iam-roles-service ↩︎

  2. https://aws.amazon.com/jp/blogs/security/how-to-use-the-passrole-permission-with-iam-roles/ ↩︎

Discussion