AssumeRole について DiveDeep する

記事タイトルとURLをコピーする

コーヒーと DiveDeep が好きな木谷映見です。

皆さん、IAM を利用する際、「AssumeRole」というアクションを目にしたことはありますか?恐らく多くの方がかなりの回数目にしているのではないでしょうか。
私は特にこの「AssumeRole」というアクションが大好きです。目立たないけれど、いつもたくさんのサービスの裏で活躍している究極の縁の下の力持ち、いいやつですよね。

本日は AssumeRole について DiveDeep していきます。

IAM ロールはかぶると力を得る帽子

IAM ロールは帽子のようなもの、というたとえを足蹴く使ってまいります。「かぶると力を得るもの」というイメージです。

お面でも構いません。「かぶると力を得るもの」とお考えいただければ、魔導士のフードでも構いません。
かぶると力を得る代わりに、もともと持っていた力は失われます。強い力を得ると我を失ってしまう展開、ありますよね。
さてこの「引き受ける」「かぶる」という動作、内部的にはどうなっているのでしょうか。

AssumeRole とは

英単語の「assume」には「引き受ける」という意味があります。
IAM ロールを引き受けるアクション」のことを、概ね sts:AssumeRole と言います。
帽子の形のアイコンにちなんで何度か「IAM ロールという帽子をかぶる」と表現をしていますが、この「かぶる」「引き受ける」というアクションをまずイメージしてください。

stsとは AWS Security Token Service という一時的認証情報をつかさどるサービスです。

sts:AssumeRole というアクションの裏側では AWS STS が一時的な認証トークンを発行しています。この STS の動きをお伝えする中で、以下の IAM ポリシーが登場します。

  • アイデンティティベースのポリシー
  • リソースベースのポリシー
    • IAM ロールの信頼ポリシー

詳細はこちらのブログの IAM ポリシーの種類 でもご紹介しておりますが、以下にも簡単に記載します。ご一読いただけますと、このあとお伝えする内容が理解しやすくなります。

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

  • IAM ユーザー、IAM グループ、IAM ロールに付与される
  • IAM ユーザー、IAM グループ、IAM ロールが何をしてよいか書かれている
    AWS 公式ドキュメントを見ますと、IAM ユーザー、IAM ユーザーグループ、 IAM ロールの 3 つをまとめて「アイデンティティ」と呼んでいます。それゆえ「アイデンティティベースのポリシー」と呼ぶようです。「IDベースのポリシー」「ユーザーベースのポリシー」と呼ばれることもあるようです。

リソースベースのポリシー

  • AWS リソースに付与される
  • 誰がAWS リソースを操作できるか書かれている
  • 「誰が」は "Principal" で記載する

    "Principal" に記載されているもの(人)を信頼している、みたいなイメージです。
    すべての AWS サービスがリソースベースのポリシーをサポートしているわけではありません。リソースベースのポリシーをサポートする AWS サービスの一覧は、 IAM と連携するサービス をご参照ください。

IAM ロールの信頼ポリシー

  • リソースベースのポリシーの一種
  • IAM ロールに付与される
  • 誰が IAM ロールを引き受ける(かぶる)か書かれている
  • 「誰が」は "Principal" 、「引き受ける(かぶる)」は "Action": "sts:AssumeRole" で記載する

IAM ロールはアイデンティティベースのポリシーと、 IAM ロールの信頼ポリシーを両方持てます。

はい、最後の IAM ロールの信頼ポリシーで "Action": "sts:AssumeRole" が登場しました。
IAM ロールを引き受ける(かぶる)アクションである "Action": "sts:AssumeRole" について、以下 2 パターン見ていきましょう。

IAM ユーザーが引き受ける(かぶる)場合

IAM ユーザーが IAM ロールを引き受けるパターン、いわゆる「スイッチロール」です。
IAM ユーザーが IAM ロールを引き受けるとき、各種ポリシーには以下のような設定が必要です。 IAM ロールの信頼ポリシーで「IAM ユーザーを信頼するポリシー」と書いているのは、"Principal" に IAM ユーザーが指定されているということです。
後ほど IAM ポリシーの例を記載します。

IAM ユーザーが IAM ロールを引き受けるときの流れは大まかに以下のようになります。

①(前提)IAM ユーザーに付与されたアイデンティティベースのポリシーで IAM ロールを引き受ける(AssumeRole)アクションが許可されている
②IAM ユーザーが IAM ロールを引き受けよう(AssumeRole)とする
③STS が 信頼ポリシーの "Principal" を確認し、IAM ロールを引き受けていいか判断する
④STS が "Principal"(今回は IAM ユーザー)に一時トークンを発行する
⑤IAM ユーザーは発行された一時トークンを使い、 IAM ロールに付与されているアイデンティティベースのポリシーで許可された操作ができるようになる

この時の IAM ユーザのアイデンティティベースのポリシーの例を以下に記載します。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::111111111111:role/test_EC2ReadOnlyAccess_Role"
    }
}

"Resource" には、かぶる IAM ロールの ARN が入っています。

IAM ロールのアイデンティティベースのポリシーはご自由に設定ください。今回は試しに AmazonEC2ReadOnlyAccess を付与してみました。 IAM ロールの信頼ポリシーの例を以下に記載します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Principal": {
                "AWS": "222222222222"
            },
            "Condition": {}
        }
    ]
}

222222222222 には、IAM ロールをかぶせる IAM ユーザが所属する AWS アカウント ID が入ります。このように AWS アカウント ID を記載すると、記入した AWS アカウントのエンティティ(要素、リソース)が、このアカウントでアクションを実行することを許可します。
2022/8/9 時点で AWS マネジメントコンソールから IAM ロールを作成しますと、デフォルトで上記のように信頼ポリシーが作成されます。この書き方ですと、 222222222222 に存在する IAM ユーザーや AWS リソースなどすべてのエンティティが、この IAM ロールを引き受ける(AssumeRole する)ことができる、ということを表します。
これだと最小権限のルールに則っておらず権限が緩すぎますので、できるだけ IAM ロールを引き受ける(AssumeRole する) IAM ユーザーを以下のように指定してあげましょう。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:user/user_A"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

一時的な認証情報の有効期間は、3,600~43,200 秒 (1~12 時間) の間で設定できます。

例外

IAM ロールと、それを引き受ける(AssumeRoleする)IAM ユーザーが同じアカウント内に存在し、かつ、IAM ロールの信頼ポリシーの Principal で IAM ユーザーを指定して許可している場合、IAM ユーザー側のアイデンティティベースのポリシーで明示的に "sts:AssumeRole" アクションを許可しなくても IAM ロールを引き受ける(AssumeRole)ことができます。

何を言っているのかと言いますと、図ではこういう感じです。 IAM ロールの信頼ポリシーの例の一つ目で示したように、 "Principal" で AWS アカウント ID をダイレクトに記載しているなど、IAM ユーザーを明示的に指定していない場合は、IAM ユーザー側のアイデンティティベースのポリシーで明示的に "sts:AssumeRole" アクションを許可する必要があります。

AWS リソースが引き受ける(かぶる)場合

AWS リソースが IAM ロールを引き受けるときも、 先ほどの IAM ユーザーが IAM ロールを引き受ける(AssumeRole)パターンと動きはほぼ同じです。 各種ポリシーには以下のような設定をしておきます。
IAM ロールの信頼ポリシーで「Lambda を信頼するポリシー」と書いているのは、"Principal" に Lambda が指定されているということです。後ほど IAM ポリシーの例を記載します。

Lambda が IAM ロールを引き受けるときの流れは大まかに以下のようになります。

①Lambda が IAM ロールを引き受けよう(AssumeRole)とする
②STS が信頼ポリシーの "Principal" を確認し、IAM ロールを引き受けていいか判断する
③STS が "Principal"(今回は Lambda )に一時トークンを発行する
④Lambda は発行された一時トークンを使い、 IAM ロールに付与されているアイデンティティベースのポリシーで許可された操作ができる

Lambda のアイデンティティベースのポリシーはご自由に設定ください。AWS マネジメントコンソールから Lambda 関数を作成する場合、デフォルトで 「AWSLambdaBasicExecutionRole-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx」という、CloudWatch のロググループの作成とログ記録を許可する以下のような IAM ロールが生成されます。

Lambda 関数の作成画面
作成された IAM ロール AWSLambdaBasicExecutionRole-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ↓

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:ap-northeast-1:333333333333:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:ap-northeast-1:333333333333:log-group:/aws/lambda/my_lambda:*"
            ]
        }
    ]
}

IAM ロールの信頼ポリシーの例を以下に記載します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

IAM ロールを「引き受ける」「かぶる」とは

ここまでお読みいただいた皆さまには、IAM ロールの裏で STS がどのように作用して、どのように認証情報が提供されているか、ご理解いただけたと思います。
IAM ロールのアイコンが帽子であり、「AWS サービスにかぶせるイメージ」などと言われる理由は、IAM ロールが持っている権限を、まるでかぶせたかのように他の IAM ユーザーや AWS リソースが使うことができるからですね。

さいごに

permissions boundaries やセッションポリシーなど考えるともっともっと DiveDeep できる余地があるのですが、今回はここまでにします。続編をお待ちください。
ここまでお読みいただいた皆さまは、「AssumeRole ってなんなの?」と質問されたとき、「ふふふそれはね」と少しドヤ顔で説明ができるようになっているはずです。

魔導士のフードをかぶって、強い力とよりよいサービス提供を目指してまいります。

参考

docs.aws.amazon.com

blog.serverworks.co.jp

ひとりごと

この先に技術的な内容は書かれていません。著者のひとりごとになります。
AWS を扱うエンジニアは自己紹介の際「好きな AWS サービスは○○です」という風潮がありますね。もとは AWS 社内の方々の間で定番になっている自己紹介らしいのですが、私はしばらく「好きな AWS サービスは○○です」と言えずにいました。好きなサービスが決められなかったのです。
もともと特定の推しをあまり作らず「みんなそれぞれ魅力があっていいよね~」という博愛傾向があるのですが、ここ最近、「君のこと、好きかも」と思えるサービスができました。
それが、今回 DiveDeep しました「"sts:AssumeRole"」です。サービスじゃなくてアクションじゃん、とお思いの方、その通りですね。厳密にサービス名を決めるとしたら「AWS IAM」が好き、ということになるのでしょうか。
何をしていてもどこにいても顔を出してくる "sts:AssumeRole" 、目立たないけれど、いつもたくさんのサービスの裏で活躍している究極の縁の下の力持ち、いいやつですよね。友達だと思ってずっと一緒にいたらいつの間にか好きになってしまった幼馴染のような存在です。(※著者は転勤族家庭で育っており幼馴染とはほぼ縁がありません)
次回から自己紹介をするとき、硬めの場であれば「好きな AWS サービスは AWS IAM です 」、やや砕けた場であれば「好きな AWS アクションは "sts:AssumeRole" です」と言ってみようと思います。
雑談にまでお付き合いいただき、誠にありがとうございました。

emi kitani(執筆記事の一覧)

AS部LX課。2022/2入社、コーヒーとサウナが好きです。執筆活動に興味があります。AWS認定12冠。