AWS AssumeRoleとかの話
背景
AWSを使い始めた時に教えて欲しかったAssumeRoleの説明を文書化します。昔の私と同じように理解に困っている人が読んでくれたら嬉しいです。
1. Role、Policyを現実に当てはめて理解する
AWSに限らず、Role(ロール)は役割を意味する英単語です。単純に考えればロールに対して権利(Right)が存在するでしょう。例としては、部長ロールを持っている人は決済権を持っているなどですね。
AWSでは、ロールに対して権利ではなく、Policy(ポリシー、方針、ルール)という名前で具体的な実行可能/不可能なことを定めるようになっています。ポリシーは権利よりも少し広い意味を持っているため、ポリシーという言葉を採用したのかなと思っています。(ポリシーには「〜してはいけない」のように否定も含まれますから)
さらに、それらの構造として下記の1番のように「ユーザに対して直接ポリシーを与える」のではなく、2番のように「ポリシーをロールに与え、そのロールをユーザに与える」ようになっています。
- 社員A(ユーザ)に決済権限(ポリシー)を与える
- 社員A(ユーザ)に部長職(ロール)を与え、部長は決済権限(ポリシー)を持つ
またポリシーを一つ掘り下げると、AWSには二種類のポリシー「許可ポリシー」と「信頼ポリシー」があります。それぞれ以下の目的があります。
- 許可ポリシー
- やっていい事・ダメな事、何に対してそれをやっていいかを定義する。
- 信頼ポリシー
- だれをどのような条件で信じて[1]許可ポリシーを利用させるのか定義する。
AWSのそれぞれの要素を会社で例えると、以下のような置き換えになるかと思います。
ポリシーには、Action や Resource、Principal などの項目を設定できます。それぞれ以下のような整理です。
- Action: どのような行動を取れるか/禁止するか
- Resource: アクションの影響範囲. 例)dev環境のRDSのみに影響など
- Principal: アクションを使っても良いとされる主体(ユーザ、サービスなど)
余談ですが、信頼ポリシーと許可ポリシーが分かれているのは非常に秀逸だなと思いました。前者は主語と述語を、後者は動詞と目的語を表していると考えても面白いです。
具体的に「営業部員である社員Aは部長になって、営業部の決済を行うことができる」を英語にすると以下のようになるでしょう。
A sales employee, Mr. A, can become a manager who is authorized to approve sales transactions.
- a sales employee, Mr. A, can become a manager => 信頼ポリシー
- authorized to approve sales transactions => 許可ポリシー
2. ここでAssumeRoleの登場
Assumeとは「~とみなす」とか「~を担う」という意味です。そのため初見では、AssumeRoleという単語を見て以下のどちらかかなと推測しました。
- 「AssumeRole = アクション」説
- => 「ロール(役割)をAssume(担う)するという行動」を表すという理解
- 「AssumeRole = ロール」説
- => 「何かをAssume(担う)したロール(役割)」が存在するという理解
正解は「1番」で、「AssumeRole = 別のロールを担うというアクション」でした。
このような理解ができて以降、AssumeRoleをロールと区別するため、心の中では「AssumeRoleアクション」と呼んでいます。(本記事では、これ以降「AssumeRoleアクション」と書きます。)
実際のところ、AssumeRoleの正式名称はsts:AssumeRole
でAWS Security Token Serviceに定義されたAPI アクションの一つです。
3. AssumeRoleアクションによって何ができるか
シンプルにロールを付与できる
まずロールには、信頼ポリシーの中で sts:AssumeRole を許可する設定が必要です。これがないと、誰もそのロールを担うこと(Assume)ができません。誰も信頼しないということです。
アカウントを跨いでロールを付与できる
例えば、信頼ポリシーのPrincipalに以下のように特定のAWS IAM arn:aws:iam::1234567890:DevUser
を設定すると、DevUserはこの信頼ポリシーが定義されたロールを担う(Assume)ことができます。別のAWSアカウント(1234567890)で定義されたIAMユーザに対して操作を許可できます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:DevUser"
},
"Action": "sts:AssumeRole"
}
]
}
ユーザ以外にも、サービスなどあらゆるものにロールを付与できる
LambdaやAWS Batchなど、スクリプトを実行するサービスに対してロールを割り当てることができるようになります。
特にLambdaに対しては、さまざまな許可ポリシーを設定することがあると思いますが、同時に信頼ポリシーとして特定のLambda関数のみを信頼するようにしておくと、ロールの割り当てミスを防ぐことができます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
# Lambdaサービスを信頼する
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
# Lambdaの中でも、my-functionだけを信頼する
"StringEquals": {
"aws:SourceArn": "arn:aws:lambda:us-west-2:1234567890:function:my-function"
}
}
}
]
}
まとめ
AWSを勉強し始めた頃、ちょっとした勘違いでAssumeRoleをロールとして理解しようとしてしまい、ドツボにハマったことを思い出し、記事を書いてみました。
ロール、ポリシー、アクションなどの理解を整理し、その後でAssumeRoleが何に当たるのかを考えると理解が整理されると思いました。
私も最初混乱していたので、この記事が誰かの助けになれば幸いです。誤りや補足があればコメントなどで教えていただけると嬉しいです。
-
ひとえに「信じる」といっても色々な方法やオプションがあるので、「許可ポリシー」と「信頼ポリシー」が分かれているとも考察しても面白いかもしれません。ロールを利用できる時間を指定したり、AWS以外のSAML Ipdを信じてAWSを操作できるようにしたり(AssumeRoleWithSAMLを使う)といった感じです。 ↩︎
Discussion