この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
arn:${Partition}:iam::${Account}:assumed-role/${RoleName}/${RoleSessionName} なんてあるのか?
コンバンハ、千葉(幸)です。
突然ですがわたしは AssumeRole (IAM ロールを引き受ける)が好きです。AssumeRole するさまを「お面を被る」と表現するのが好きです。
▲ お面を被って力を得ている図
IAM ユーザーが別の AWS アカウントにある IAM ロールを引き受けるケースを考えると、それぞれの ARN は以下の通りです。
arn:aws:iam::999999999999:user/ユーザー名
arn:aws:iam::000000000000:role/ロール名
arn:aws:sts::000000000000:assumed-role/ロール名/セッション名
3つ目の 「IAM ロールを引き受けたセッション(Assumed-role セッション)」のみ、サービスの名前空間がsts
です。サービスの名前空間とは、今回の例で言えばarn:aws:
の後にくる部分を指します。 *1
「正しくはsts
だけどうっかりiam
と間違いがちなところだよね〜」などと思っていたのですが、公式のリファレンスでiam
が入っているパターンを見つけてしまいました。
AssumeRole 大好きおじさんとしては、「sts
以外は認められない。これは誤りでは?ということは遂にわたし自身がリファレンスになる時が来たのでは?」などと思っていたのですが、もしかしたらiam
にしても正常に動作するのかもしれない、と思い、試してみることにしたのであった。
まとめ
- 構文としてはサービス名前空間が
iam
でも間違ってはいない - ただし設定値として保存される際には
sts
に自動で置き換えられる - 捕まえたと思ったら手のひらから零れ落ち逃げていくような儚さを感じる
sts で合ってるよな?という土台を固める
iam
でも正しく動くのか?を確かめる前に、急に不安になってきたのでsts
が正しいかどうかを調べます。
とは言っても実際に AssumeRole した後にプリンシパルを確認すればsts
になっているので、一目瞭然ではあります。
# AssumeRole を実行し環境変数を設定
% OUTPUT=$(aws sts assume-role --role-arn arn:aws:iam::000000000000:role/IAMRoleA --role-session-name hoge)
export AWS_ACCESS_KEY_ID=$(echo $OUTPUT | jq -r .Credentials.AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $OUTPUT | jq -r .Credentials.SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $OUTPUT | jq -r .Credentials.SessionToken)
# プリンシパルの確認
% aws sts get-caller-identity
{
"UserId": "AROAQ3BIIH736BYCRY6IV:hoge",
"Account": "000000000000",
"Arn": "arn:aws:sts::000000000000:assumed-role/IAMRoleA/hoge"
}
そのほかの例で言うと IAM ARN の構文を見るとsts
になっていますし、
JSON ポリシーの Principal 要素で Assumed-role セッションプリンシパルを指定する際の書き方もsts
になっています。
むしろこれで「iam
でも書けます」と言われても少し困ってしまうな、と言うレベルでsts
が正しそうです。
でも iam で書いてある例があるなぁ
とは言っても冒頭で引用した例ではiam
で表されています。そしてそもそもこれを調べようと思ったきっかけは以下の記述を見かけたことです。
これは IAM AcceccAnalyzer によるポリシーチェック項目のリファレンスです。IAM ロール信頼ポリシーで冗長な書き方をした時にその除去を提案してくれる項目の例として書かれています。
初見で「誤記では?」と思ったのですが、実際に信頼ポリシーの編集画面で再現してみるときちんと提案が行われました。
(↓ちなみにsts
に置き換えても同じ提案がされます。)
ここで1番目の画像の状態、つまりiam
にした状態でポリシーを保存しても、なぜかsts
に置き換わっていました。 *2
不思議動作だ。
AWS マネジメントコンソールで試してみる
もうちょっと挙動を確認するために以下のポリシーの Principal 要素にiam
の Assumed-role セッションプリンシパルを指定してみます。
- S3 バケットポリシー
- IAM ロール信頼ポリシー
S3 バケットポリシー
この状態で保存を試みます。
sts
に変わっていました。
なるほど。
IAM ロール信頼ポリシー
この状態で保存を試みます。
お、更新後もiam
のまま表示されました!
勢い余ってページをリロードしたらsts
に変わっていました。
そうですか。
AWS CLI で試してみる
AWS マネジメントコンソールは気を利かせていろいろやってくれることがあるので、AWS CLI での挙動も確認してみます。
S3 バケットポリシー
以下コマンドでバケットポリシーを設定します。
# 変数にバケットポリシーの中身を格納
% policy=$(cat <<EOM
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::012345678910:assumed-role/IAMRoleA/hoge"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::chibayuki-hoge-hoge/*"
}
]
}
EOM
)
# 上記の変数を指定してコマンド実行
% aws s3api put-bucket-policy --bucket chibayuki-hoge-hoge --policy "$policy"
設定後にポリシーを確認したところ、sts
に置き換わっていました。
% aws s3api get-bucket-policy --bucket chibayuki-hoge-hoge | jq -r .Policy | jq .
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::012345678910:assumed-role/IAMRoleA/hoge"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::chibayuki-hoge-hoge/*"
}
]
}
ふーむ。
IAM ロール信頼ポリシー
以下コマンドで IAM ロールを作成します。(信頼ポリシーだけ設定するコマンドはなさそうでした。)
# 変数に信頼ポリシーの中身を格納
% policy=$(cat <<EOM
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::012345678910:assumed-role/IAMRoleA/hoge"
},
"Action": "sts:AssumeRole"
}
]
}
EOM
)
# 上記の変数を指定してコマンド実行
% aws iam create-role --role-name hoge --assume-role-policy-document "$policy"
{
"Role": {
"Path": "/",
"RoleName": "hoge",
"RoleId": "AROAQ3BIIH73SQIEWG7ZS",
"Arn": "arn:aws:iam::012345678910:role/hoge",
"CreateDate": "2022-10-04T17:53:04+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::012345678910:assumed-role/IAMRoleA/hoge"
},
"Action": "sts:AssumeRole"
}
]
}
}
}
↑コマンドの戻り値ではiam
のままになっています!
その後に信頼ポリシーを確認すると、sts
に置き換わっていました。
% aws iam get-role --role-name hoge
{
"Role": {
"Path": "/",
"RoleName": "hoge",
"RoleId": "AROAQ3BIIH73SQIEWG7ZS",
"Arn": "arn:aws:iam::012345678910:role/hoge",
"CreateDate": "2022-10-04T17:53:04+00:00",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::012345678910:assumed-role/IAMRoleA/hoge"
},
"Action": "sts:AssumeRole"
}
]
},
"MaxSessionDuration": 3600,
"RoleLastUsed": {}
}
}
そうですか。
まとめ(再掲)
- 構文としてはサービス名前空間が
iam
でも間違ってはいない - ただし設定値として保存される際には
sts
に自動で置き換えられる - 捕まえたと思ったら手のひらから零れ落ち逃げていくような儚さを感じる
終わりに
Assumed-role セッションプリンシパルのサービス名前空間をiam
にしてみたけどそっとsts
に置き換えられた、という話でした。
プリンシパルの構文としては誤っていないため設定リクエストは正常に通りますが、iam
のまま設定値が落ち着くということはなさそうでした。いっそのことsts
じゃないとリクエストが成功しないようにしてくれれば分かりやすいのに、とも思いますが、どこか儚さを感じて風流な気もしてきたのでこれはこれでいいと思えてきました。
「iam
で合ってるんだっけ?」と疑問に思う方が世界に80人くらいはいると思うので、そんな方の参考になれば幸いです。
以上、 チバユキ (@batchicchi) がお送りしました。
参考
- AWS JSON policy elements: Principal - AWS Identity and Access Management
- IAM ID - AWS Identity and Access Management
- Identity and Access Management のアクション、リソース、および条件キー - サービス認証リファレンス
- Access Analyzer policy check reference - AWS Identity and Access Management
脚注
- Amazon リソースネーム (ARN) - AWS 全般のリファレンス ↩
- さらに言うとプリンシパルの順番も入れ替わっていますが、そこはあまり重要じゃないのでサラッと流しておきます。 ↩