- 技術 💻
IAMロールとは|ユーザー・ポリシーとの違いとAssumeRole、信頼ポリシー
IAMロールとは、パスワードやアクセスキーを持たず、「引き受けた(AssumeRole した)相手」に期限つきの一時的な認証情報を渡す、AWS の権限の入れ物です。 IAMユーザーが「人やアプリに 1 対 1 で発行する長期の ID」であるのに対し、ロールは「必要なときだけ借りる権限」です。ロールには 2 種類のポリシーが付きます。誰が引き受けられるかを決める「信頼ポリシー」と、引き受けたあとに何ができるかを決める「許可ポリシー」です。
この記事では、ユーザー・グループ・ロール・ポリシーの違いを比較表で整理したうえで、create-role → attach-role-policy → sts assume-role → 一時的な認証情報での get-caller-identity までを、コマンドと出力 JSON をそのまま載せて通します。設定ファイルの role_arn / source_profile による自動切り替え、Principal の書き方一覧、「is not authorized to perform: sts:AssumeRole」が出たときの切り分け表も用意しました。
確認環境:Ubuntu 24.04、AWS CLI 1.46.1、boto3 1.43.103、Python 3.11。AWS の API をローカルで再現するツール(moto 5.2.3)で実行しました。掲載するコマンドは、ローカル向けの接続先指定を外して AWS でそのまま使える形にしています。アカウント ID は例示用の 123456789012 です。
IAMロールの早見表(ユーザー・グループ・ロール・ポリシーの違い)
4 つの違いは「誰が使うか」「認証情報の種類」「有効期限」の 3 点で見ると整理できます。 ユーザーとロールは「ID(誰であるか)」、グループは「ユーザーの束」、ポリシーは「権限を書いた JSON 文書」です。
| 種類 | ひとことで | 誰が使うか | 認証情報の種類 | 有効期限 | Principal に書けるか |
|---|---|---|---|---|---|
| IAMユーザー | 人やアプリに 1 対 1 で発行する ID | 特定の 1 人、または 1 つのアプリ | パスワード、アクセスキー(長期) | 期限なし(削除・交換するまで有効) | 書ける |
| IAMグループ | ユーザーをまとめる束 | 所属するユーザー全員(グループ自体は使えない) | なし | なし | 書けない |
| IAMロール | 必要なときに引き受ける権限の入れ物 | 信頼ポリシーで許可された人・AWS サービス・外部 ID | 一時的な認証情報(アクセスキー+シークレット+セッショントークン) | 15 分〜12 時間(既定 1 時間) | 書ける |
| ポリシー | 権限を書いた JSON 文書 | ユーザー・グループ・ロールに付けて使う | なし(ID ではない) | なし | 対象外 |
続いて、ロールに付く 2 種類のポリシーの早見表です。
| 項目 | 信頼ポリシー | 許可ポリシー |
|---|---|---|
| 決めること | 誰がこのロールを引き受けられるか | 引き受けたあと何ができるか |
| ロール 1 つに付く数 | 必ず 1 つ | 0 個以上(管理ポリシー・インラインポリシー) |
| 必須の要素 | Principal(相手)と Action(sts:AssumeRole など) |
Action(操作)と Resource(対象) |
Principal |
書く | 書かない |
Resource |
書かない(ロール自身が対象) | 書く |
| 指定するコマンド | create-role --assume-role-policy-document、update-assume-role-policy |
attach-role-policy、put-role-policy |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「IAMロールとは|ユーザー・ポリシーとの違いとAssumeRole、信頼ポリシー」
IAMロールのしくみを 3 ステップでつかむ
ロールを使う流れは「引き受けを申し込む → 一時的な認証情報を受け取る → その認証情報で操作する」の 3 ステップです。 窓口になるのが AWS STS(Security Token Service)という、一時的な認証情報を発行するサービスです。
sequenceDiagram
participant U as IAMユーザー taro
participant S as AWS STS
participant R as ロール s3-readonly-role
participant A as S3 などのサービス
U->>S: 1. sts:AssumeRole(ロールのARNを指定)
S->>R: 信頼ポリシーを確認(taro は引き受けてよいか)
S-->>U: 2. 一時的な認証情報(期限つき)
U->>A: 3. 一時的な認証情報で操作
A->>R: 許可ポリシーを確認(この操作はしてよいか)
A-->>U: 結果
ポイントは 2 つあります。
- ロールを引き受けている間は、ロールの許可ポリシーだけが効きます。 元のユーザーの権限に足されるのではなく、いったん切り替わります。
- 一時的な認証情報は期限が来ると自動で使えなくなります。 アクセスキーを配って回収する運用が要らなくなるのが、ロールのいちばんの利点です。
AWS の公式ドキュメント(IAM Identities)でも、外部の ID プロバイダーと連携した ID がロールを引き受けて AWS のリソースにアクセスする形や、IAM Identity Center が必要なロールを自動で作る形が紹介されています。
信頼ポリシーと許可ポリシーの JSON を並べて読む
2 つのポリシーは見た目がよく似ていますが、「Principal があるほうが信頼ポリシー、Resource があるほうが許可ポリシー」と覚えると見分けられます。 今回使う 2 つのファイルを並べます。
信頼ポリシー(trust.json):ユーザー taro に引き受けを許可する
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:user/taro" },
"Action": "sts:AssumeRole"
}
]
}
許可ポリシー(perm.json):S3 の読み取りを許可する
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": "*"
}
]
}
要素ごとに横に並べると、役割の違いがはっきりします。
| 要素 | 信頼ポリシー(trust.json) | 許可ポリシー(perm.json) |
|---|---|---|
Effect |
Allow(引き受けを許可) |
Allow(操作を許可) |
Principal |
{"AWS": "arn:aws:iam::123456789012:user/taro"} = 引き受けてよい相手 |
なし(付けた先のロールが主語になる) |
Action |
sts:AssumeRole = 引き受けという操作 |
s3:GetObject、s3:ListBucket = 引き受けたあとの操作 |
Resource |
なし(このロール自身が対象) | *(対象のリソース。バケットの ARN に絞れる) |
| 文章にすると | 「taro は、このロールを引き受けてよい」 | 「このロールは、S3 のオブジェクトを読んでよい」 |
信頼ポリシーは「ロールというリソースに付くポリシー(リソースベースのポリシー)」、許可ポリシーは「ロールという ID に付くポリシー(アイデンティティベースのポリシー)」です。 ロールは「引き受けられる対象」でもあり「操作する主体」でもあるので、両方が必要になります。
create-role から assume-role まで通しで実行する
ここからは、ロールを作って引き受けるまでを順番に実行します。前提として、IAMユーザー taro が作成済みで、上の trust.json と perm.json が手元にある状態です。
1. 切り替え前の自分を確認する(get-caller-identity)
aws sts get-caller-identity は「いま、誰として AWS を操作しているか」を返すコマンドです。 ロールの切り替えを確かめるときの基準になります。
aws sts get-caller-identity
{
"UserId": "rqasbmbxuu1lj6fif3qk",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/taro"
}
Arn が arn:aws:iam::…:user/taro なので、IAMユーザー taro として操作しています。
2. ロールを作る(create-role)
ロールの作成時に必ず渡すのが信頼ポリシーです。 --assume-role-policy-document にファイルを指定します。
aws iam create-role \
--role-name s3-readonly-role \
--assume-role-policy-document file://trust.json
{
"Role": {
"Path": "/",
"RoleName": "s3-readonly-role",
"RoleId": "AROARZPUZDIKDDOG2OAAS",
"Arn": "arn:aws:iam::123456789012:role/s3-readonly-role",
"CreateDate": "2026-10-03T09:40:06.996468Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/taro"
},
"Action": "sts:AssumeRole"
}
]
},
"MaxSessionDuration": 3600,
"RoleLastUsed": {}
}
}
出力で見ておきたいのは 3 か所です。
| キー | 意味 |
|---|---|
Arn |
ロールの ARN。assume-role の --role-arn や設定ファイルの role_arn に書く |
RoleId |
ロールの固有 ID(この出力では AROA で始まる)。引き受けたあとの UserId の前半になる |
MaxSessionDuration |
1 回の引き受けで発行できる最長の秒数。既定は 3600(1 時間) |
この時点のロールは「taro が引き受けられるが、何もできない」状態です。許可ポリシーをまだ付けていないためです。
3. 許可ポリシーを作って付ける(create-policy / attach-role-policy)
許可ポリシーは、管理ポリシーを作って attach-role-policy で付けるのが基本です。
aws iam create-policy \
--policy-name s3-read-policy \
--policy-document file://perm.json
{
"Policy": {
"PolicyName": "s3-read-policy",
"PolicyId": "A4U67GMJG7VO3BQX9MX85",
"Arn": "arn:aws:iam::123456789012:policy/s3-read-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"IsAttachable": true,
"CreateDate": "2026-10-03T09:40:07.379979Z",
"UpdateDate": "2026-10-03T09:40:07.379983Z"
}
}
aws iam attach-role-policy \
--role-name s3-readonly-role \
--policy-arn arn:aws:iam::123456789012:policy/s3-read-policy
attach-role-policy は成功すると何も出力しません。付いたかどうかは list-attached-role-policies で確認します。
aws iam list-attached-role-policies --role-name s3-readonly-role
{
"AttachedPolicies": [
{
"PolicyName": "s3-read-policy",
"PolicyArn": "arn:aws:iam::123456789012:policy/s3-read-policy"
}
]
}
AWS があらかじめ用意している管理ポリシーを付ける場合は、--policy-arn に arn:aws:iam::aws:policy/ポリシー名 の形の ARN を指定します(アカウント ID の位置が aws になります)。
ロールだけで使う権限なら、ロールに直接書き込むインラインポリシーも選べます。
aws iam put-role-policy \
--role-name ec2-app-role \
--policy-name inline-s3 \
--policy-document file://perm.json
aws iam list-role-policies --role-name ec2-app-role
{
"PolicyNames": [
"inline-s3"
]
}
| 付け方 | コマンド | 一覧の確認 | 向いている場面 |
|---|---|---|---|
| 管理ポリシー | attach-role-policy |
list-attached-role-policies |
複数のロールで同じ権限を使い回す |
| インラインポリシー | put-role-policy |
list-role-policies |
そのロール専用の権限を 1 か所にまとめる |
4. ロールを引き受ける(sts assume-role)
aws sts assume-role には、ロールの ARN とセッション名の 2 つが必須です。 セッション名は「誰がこのロールを使っているか」を示す名札で、2〜64 文字の英数字と _+=,.@- が使えます(AWS STS の API リファレンス)。
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/s3-readonly-role \
--role-session-name taro-session \
--duration-seconds 900
{
"Credentials": {
"AccessKeyId": "ASIARZPUZDIKKN5QQ2EQ",
"SecretAccessKey": "GLSzCk16p0ZkA9oviCIJA/b+qNAPHi9ZPYT9JeSD",
"SessionToken": "FQoGZXIvYXdzEBYaDhqk/F4RNskM9cZVzQkIe6NDOzMU5iyXJTnh1my6U9ke...(長いので省略)",
"Expiration": "2026-10-03T09:55:08.510861Z"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROARZPUZDIKDDOG2OAAS:taro-session",
"Arn": "arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session"
},
"PackedPolicySize": 6
}
これが一時的な認証情報です。4 つの値の意味は次のとおりです。
| キー | 意味 | 環境変数に入れるとき |
|---|---|---|
AccessKeyId |
一時的なアクセスキー(この出力では ASIA で始まる) |
AWS_ACCESS_KEY_ID |
SecretAccessKey |
一時的なシークレットキー | AWS_SECRET_ACCESS_KEY |
SessionToken |
セッショントークン。一時的な認証情報にはこれが必須 | AWS_SESSION_TOKEN |
Expiration |
期限(UTC)。この例は --duration-seconds 900 なので 15 分後 |
(設定しない) |
AssumedRoleUser.Arn の形にも注目してください。arn:aws:sts::アカウント:assumed-role/ロール名/セッション名 となり、ロールそのものの ARN(arn:aws:iam::…:role/…)とは別物です。
--duration-seconds の下限は 900 秒です。それより小さい値を渡すと、CLI が送信前に止めてくれます。
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/s3-readonly-role \
--role-session-name xx --duration-seconds 100
Parameter validation failed:
Invalid value for parameter DurationSeconds, value: 100, valid min value: 900
5. 一時的な認証情報で操作する(get-caller-identity)
受け取った 3 つの値を環境変数に入れると、以降のコマンドはロールとして実行されます。
export AWS_ACCESS_KEY_ID=ASIARZPUZDIKKN5QQ2EQ
export AWS_SECRET_ACCESS_KEY=GLSzCk16p0ZkA9oviCIJA/b+qNAPHi9ZPYT9JeSD
export AWS_SESSION_TOKEN=FQoGZXIvYXdzEBYa...(assume-role の SessionToken 全体)
aws sts get-caller-identity
{
"UserId": "AROARZPUZDIKDDOG2OAAS:taro-session",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session"
}
切り替え前と比べると、次のように変わっています。
| 項目 | 切り替え前(ユーザー) | 切り替え後(ロール) |
|---|---|---|
Arn |
arn:aws:iam::123456789012:user/taro |
arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session |
UserId |
ユーザーの固有 ID | ロールの RoleId:セッション名 |
| 効く権限 | taro に付いたポリシー | s3-readonly-role に付いた許可ポリシー |
| 認証情報 | 長期のアクセスキー | 15 分で切れる一時的な認証情報 |
3 つの値を手でコピーする代わりに、--query と --output text で取り出して一度に設定することもできます。
export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \
$(aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/s3-readonly-role \
--role-session-name taro-session \
--query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
--output text))
aws sts get-caller-identity --query Arn --output text
arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session
元のユーザーに戻るときは、3 つの環境変数を unset します。
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
config の role_arn と source_profile で自動的に切り替える
毎回 assume-role を打つ代わりに、設定ファイルにロールを書いておくと、AWS CLI が裏側で AssumeRole を呼んでくれます。 書くのは role_arn(引き受けるロール)と source_profile(引き受けに使う元の認証情報)の 2 行です。
~/.aws/credentials(元になる長期の認証情報)
[base]
aws_access_key_id = AKIA................
aws_secret_access_key = ........................................
~/.aws/config(ロール用のプロファイルを追加)
[profile base]
region = ap-northeast-1
[profile readonly]
role_arn = arn:aws:iam::123456789012:role/s3-readonly-role
source_profile = base
role_session_name = taro-session
region = ap-northeast-1
あとは --profile readonly を付けるだけです。
aws sts get-caller-identity --profile readonly
{
"UserId": "AROARZPUZDIKDDOG2OAAS:taro-session",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session"
}
環境変数 AWS_PROFILE に入れておけば、--profile を毎回書かずに済みます。
export AWS_PROFILE=readonly
aws sts get-caller-identity --query Arn --output text
arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session
実行後、~/.aws/cli/cache/ に JSON ファイルが 1 つ作られていました。AWS CLI は一時的な認証情報をここに保存して使い回し、期限が切れると自動で取り直します(AWS CLI ユーザーガイド「Using an IAM role in the AWS CLI」)。ロールの権限を変えた直後などに取り直したいときは、このフォルダを消します。
rm -r ~/.aws/cli/cache
ロール用プロファイルに書ける主な設定は次のとおりです(同ユーザーガイドより)。
| 設定 | 意味 | 例 |
|---|---|---|
role_arn |
引き受けるロールの ARN | arn:aws:iam::123456789012:role/s3-readonly-role |
source_profile |
引き受けに使う元のプロファイル名 | base |
credential_source |
source_profile の代わりに、認証情報の取得元を指定 |
Environment、Ec2InstanceMetadata、EcsContainer |
role_session_name |
セッション名。CloudTrail のログやセッションの ARN に出る | taro-session |
mfa_serial |
MFA デバイスの ARN。引き受け時にコードの入力を求められる | arn:aws:iam::123456789012:mfa/taro |
external_id |
別アカウントのロールを引き受けるときの追加の合言葉 | 123456 |
source_profile と credential_source はどちらか一方を書きます。EC2 の上で動かす CLI から別のロールへ切り替えるときは credential_source = Ec2InstanceMetadata が便利です。
Python(boto3)で AssumeRole する
プログラムからも流れは同じで、assume_role の戻り値から 3 つの値を取り出し、新しいセッションを作ります。
import boto3
sts = boto3.client("sts")
res = sts.assume_role(
RoleArn="arn:aws:iam::123456789012:role/s3-readonly-role",
RoleSessionName="taro-session",
DurationSeconds=900,
)
c = res["Credentials"]
# 一時的な認証情報で新しいセッションを作る
session = boto3.Session(
aws_access_key_id=c["AccessKeyId"],
aws_secret_access_key=c["SecretAccessKey"],
aws_session_token=c["SessionToken"],
)
me = session.client("sts").get_caller_identity()
print(me["Arn"])
print("期限:", c["Expiration"])
arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session
期限: 2026-10-03 09:56:36.529720+00:00
session.client("s3") のように、この session から作ったクライアントはすべてロールの権限で動きます。
Principal の書き方一覧(アカウント・ユーザー・サービス・Federated)
信頼ポリシーの Principal は「誰に引き受けを許すか」を書く場所で、相手の種類によってキーが変わります。 IAM ユーザーガイド「AWS JSON policy elements: Principal」に載っている書き方を、相手の種類ごとにまとめました。
| 相手 | Principal の書き方 | Action | 補足 |
|---|---|---|---|
| AWS アカウント全体 | {"AWS": "arn:aws:iam::123456789012:root"} |
sts:AssumeRole |
アカウントに委任する形。相手側で個々のユーザーやロールへの許可が別途必要 |
| AWS アカウント(短縮形) | {"AWS": "123456789012"} |
sts:AssumeRole |
上と同じ意味 |
| IAMユーザー | {"AWS": "arn:aws:iam::123456789012:user/taro"} |
sts:AssumeRole |
複数なら配列で並べる |
| IAMロール | {"AWS": "arn:aws:iam::123456789012:role/role-name"} |
sts:AssumeRole |
ロールからロールへ切り替える(ロールの連鎖)ときに使う |
| ロールのセッション | {"AWS": "arn:aws:sts::123456789012:assumed-role/role-name/session-name"} |
sts:AssumeRole |
特定のセッション名だけを許可 |
| AWS サービス | {"Service": "ec2.amazonaws.com"} |
sts:AssumeRole |
EC2 や Lambda などのサービスが引き受ける。複数なら配列 |
| SAML の ID プロバイダー | {"Federated": "arn:aws:iam::123456789012:saml-provider/provider-name"} |
sts:AssumeRoleWithSAML |
社内の認証基盤などと連携 |
| OIDC の ID プロバイダー | {"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"} |
sts:AssumeRoleWithWebIdentity |
GitHub Actions などの外部 ID と連携 |
| Cognito | {"Federated": "cognito-identity.amazonaws.com"} |
sts:AssumeRoleWithWebIdentity |
アプリの利用者に一時的な権限を渡す |
同じガイドに書かれている、Principal の決まりも押さえておきます。
- IAMグループは Principal に書けません。 グループは権限をまとめるためのもので、認証される ID ではないためです。
- ARN の一部にワイルドカードは使えません。
user/dev-のあとを * でまとめる、といった書き方はできないので、ユーザーやロールを 1 つずつ並べるか、アカウント全体を指定します。 - アカウントを Principal にした場合は「委任」です。 相手アカウントの管理者が、その中のユーザーやロールに権限を与えて初めて使えます。
- ユーザーやロールの ARN を書いて保存すると、内部では固有 ID に変換されて保持されます。 そのため、相手のロールを削除して同じ名前で作り直すと、固有 ID が変わって関係が切れます。信頼ポリシーには ARN の代わりに固有 ID(
create-roleの出力にあったRoleIdのような値)が表示されるようになるので、正しい ARN に書き直します。
AWS サービスに引き受けさせるロール(EC2 の例)
サービス用のロールは、Principal を Service にするだけで、作り方は同じです。EC2 の場合はもう 1 つ、インスタンスプロファイルという入れ物にロールを入れてから EC2 に付けます。
svc.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
aws iam create-role --role-name ec2-app-role \
--assume-role-policy-document file://svc.json --query Role.Arn
aws iam create-instance-profile \
--instance-profile-name ec2-app-profile --query InstanceProfile.Arn
aws iam add-role-to-instance-profile \
--instance-profile-name ec2-app-profile --role-name ec2-app-role
"arn:aws:iam::123456789012:role/ec2-app-role"
"arn:aws:iam::123456789012:instance-profile/ec2-app-profile"
add-role-to-instance-profile は成功すると何も出力しません。サービスが引き受けるロールでは、assume-role を自分で打つ必要はありません。 たとえば EC2 の上の AWS CLI は、インスタンスプロファイルに付いたロールの認証情報をそのまま使えます(設定ファイルの credential_source = Ec2InstanceMetadata は、この認証情報を元にして別のロールへ切り替える指定です)。アプリのコードにアクセスキーを書かずに済むのはこのためです。
「is not authorized to perform: sts:AssumeRole」の切り分け表
このエラーは「引き受ける側の許可」と「引き受けられる側の信頼」のどちらか(または両方)が足りないときに出ます。 まず実際のエラー文を見ます。taro に s3-readonly-role だけの引き受けを許可した状態で、許可していない other-role を指定した例です。
taro に付けたポリシー(allow.json)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::123456789012:role/s3-readonly-role"
}
]
}
aws iam put-user-policy --user-name taro \
--policy-name allow-assume --policy-document file://allow.json
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/other-role \
--role-session-name taro-session
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::123456789012:user/taro is not authorized to perform: sts:AssumeRole
許可した s3-readonly-role を指定すると通ります。
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/s3-readonly-role \
--role-session-name taro-session --query AssumedRoleUser
{
"AssumedRoleId": "AROARZPUZDIKCKVMTMNFS:taro-session",
"Arn": "arn:aws:sts::123456789012:assumed-role/s3-readonly-role/taro-session"
}
エラー文の User: のあとに出る ARN が「いま誰として呼んだか」です。ここが想定と違っていたら、プロファイルや環境変数の指定を先に見直します。
同じアカウントか、別のアカウントかで必要なものが変わる
AWS STS の API リファレンス(AssumeRole)によると、必要な許可は次のように変わります。
| 引き受け方 | 引き受ける側(ユーザー)の許可ポリシー | ロールの信頼ポリシー |
|---|---|---|
| 同じアカウント内 | sts:AssumeRole を許可する |
そのユーザーを Principal に直接書く |
| 同じアカウント内の判定 | 上のどちらか一方があれば引き受けられる | (同左) |
| 別のアカウント | sts:AssumeRole を、相手ロールの ARN に対して許可する |
引き受ける側のアカウント(またはユーザー・ロール)を Principal に書く |
| 別のアカウントの判定 | 両方が必要 | (同左) |
原因と確認方法
IAM ユーザーガイドのトラブルシューティング(I can't assume a role)と、Principal の説明に挙がっている原因を、確認方法とあわせて表にしました。
| 原因 | 確認方法 | 直し方 |
|---|---|---|
| 呼び出している ID が想定と違う | aws sts get-caller-identity の Arn を見る |
--profile や AWS_PROFILE、環境変数を正しい ID に合わせる |
引き受ける側に sts:AssumeRole の許可がない |
ユーザーやロールの許可ポリシーに sts:AssumeRole と対象ロールの ARN があるか |
上の allow.json の形のポリシーを付ける |
| 信頼ポリシーの Principal に自分(のアカウント)が入っていない | aws iam get-role --role-name ロール名 --query Role.AssumeRolePolicyDocument |
update-assume-role-policy で Principal を足す |
| ロール名の大文字・小文字が違う | --role-arn の表記と aws iam list-roles の結果を見比べる |
ロール名は大文字・小文字が区別されるので、正確に書く |
信頼ポリシーの Condition を満たしていない |
信頼ポリシーに外部 ID・接続元 IP・期限などの条件がないか | 条件に合う形で呼ぶ(--external-id を付ける など) |
| ロールがタグの条件を求めている | 信頼ポリシーの Condition にタグの指定がないか |
引き受ける側に必要なタグを付ける |
| ソース ID の設定を求められている | 信頼ポリシーがソース ID の設定を求めていないか | 引き受け時にソース ID を指定する |
| ロールからロールへ切り替えるとき、元のロールが信頼されていない | 信頼ポリシーの Principal に元のロールの ARN があるか | 元のロールを Principal に足す |
| 相手のユーザー・ロールを作り直した | 信頼ポリシーの Principal が ARN ではなく固有 ID の表示になっていないか | Principal を正しい ARN に書き直す |
信頼ポリシーの中身は、次のコマンドですぐ見られます。
aws iam get-role --role-name s3-readonly-role \
--query Role.AssumeRolePolicyDocument
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/taro"
},
"Action": "sts:AssumeRole"
}
]
}
信頼ポリシーを直すときは update-assume-role-policy を使います。
aws iam update-assume-role-policy \
--role-name s3-readonly-role \
--policy-document file://trust.json
セッションの有効期限の決まり
一時的な認証情報の長さは「呼ぶ側が指定する秒数」と「ロール側の上限」の 2 つで決まります。 AWS STS の API リファレンスと IAM のトラブルシューティングに書かれている内容を整理します。
| 項目 | 値 |
|---|---|
--duration-seconds の下限 |
900 秒(15 分) |
--duration-seconds の既定値 |
3600 秒(1 時間) |
| 指定できる上限 | ロールの最大セッション時間(MaxSessionDuration)まで。設定できる範囲は最長 43200 秒(12 時間) |
| ロールからロールへ切り替えた場合(ロールの連鎖) | 最長 1 時間 |
ロールの最大セッション時間は、作成時の --max-session-duration で指定できます。指定しない場合、create-role の出力で見たとおり 3600 になります。
ロールの一覧・削除でよく使うコマンド
ロールを消すときは、先に許可ポリシーを外す必要があります。 付いたまま delete-role を実行すると、次のように止まります。
aws iam delete-role --role-name s3-readonly-role
An error occurred (DeleteConflict) when calling the DeleteRole operation: Cannot delete entity, must detach all policies first.
# 管理ポリシーを外してから削除
aws iam detach-role-policy --role-name s3-readonly-role \
--policy-arn arn:aws:iam::123456789012:policy/s3-read-policy
aws iam delete-role --role-name s3-readonly-role
同じ名前のロールをもう一度作ろうとした場合と、存在しないロールを指定した場合のメッセージも載せておきます。
An error occurred (EntityAlreadyExists) when calling the CreateRole operation: Role with name s3-readonly-role already exists.
An error occurred (NoSuchEntity) when calling the UpdateAssumeRolePolicy operation: Role s3-readonly-role not found
ロールの一覧は --query と --output table で表にすると読みやすくなります。
aws iam list-roles \
--query 'Roles[].[RoleName,Arn,MaxSessionDuration]' --output table
---------------------------------------------------------------------------------
| ListRoles |
+-------------------+---------------------------------------------------+-------+
| s3-readonly-role | arn:aws:iam::123456789012:role/s3-readonly-role | 3600 |
+-------------------+---------------------------------------------------+-------+
| やりたいこと | コマンド |
|---|---|
| ロールを作る | aws iam create-role --role-name 名前 --assume-role-policy-document file://trust.json |
| 信頼ポリシーを見る | aws iam get-role --role-name 名前 --query Role.AssumeRolePolicyDocument |
| 信頼ポリシーを書き換える | aws iam update-assume-role-policy --role-name 名前 --policy-document file://trust.json |
| 管理ポリシーを付ける/外す | aws iam attach-role-policy / aws iam detach-role-policy |
| インラインポリシーを書く | aws iam put-role-policy --role-name 名前 --policy-name 名前 --policy-document file://perm.json |
| 付いているポリシーを見る | aws iam list-attached-role-policies / aws iam list-role-policies |
| ロールを引き受ける | aws sts assume-role --role-arn ARN --role-session-name 名前 |
| いまの自分を確認する | aws sts get-caller-identity |
| ロールを消す | ポリシーを外してから aws iam delete-role --role-name 名前 |
ユーザーとロールのどちらを使うかの判断表
迷ったら「一時的な認証情報で済むならロール」を基準にすると選びやすくなります。
| 場面 | 選ぶもの | 理由 |
|---|---|---|
| EC2 や Lambda の中のアプリが AWS を操作する | ロール(サービスを Principal に) | アクセスキーをコードや設定に置かずに済む |
| 別の AWS アカウントのリソースを操作する | ロール(相手アカウントを Principal に) | 相手側にユーザーを作らずに、権限だけを貸し借りできる |
| ふだんは読み取りだけ、必要なときだけ強い権限を使う | ロール(自分のユーザーを Principal に) | 強い権限を期限つきで借りる形にできる |
| GitHub Actions などの外部の仕組みから操作する | ロール(OIDC の ID プロバイダーを Principal に) | 長期のアクセスキーを外部に預けずに済む |
| 社内の認証基盤でログインした人に権限を渡す | ロール(SAML の ID プロバイダー、または IAM Identity Center) | 人の出入りを 1 か所で管理できる |
| ロールを引き受けるための「元の ID」が必要 | IAMユーザー(権限は sts:AssumeRole だけに絞る) |
長期のキーが持つ権限を最小にできる |
よくある質問
Q. IAMロールとポリシーは何が違いますか? A. ロールは「誰として操作するか」を表す ID で、ポリシーは「何を許可するか」を書いた JSON 文書です。ロールに許可ポリシーを付けることで、初めてロールは操作ができるようになります。ロールにはもう 1 つ、引き受けられる相手を決める信頼ポリシーが必ず付きます。
Q. ロールを引き受けると、元のユーザーの権限はどうなりますか?
A. 引き受けている間は、ロールの許可ポリシーが効きます。記事中の get-caller-identity の結果でも、Arn がユーザーから assumed-role/… に切り替わっていました。環境変数を unset する、または別のプロファイルを指定すると元のユーザーに戻ります。
Q. 一時的な認証情報の期限が切れたらどうなりますか?
A. その認証情報では操作できなくなるので、もう一度 assume-role を呼んで取り直します。設定ファイルに role_arn と source_profile を書いておく方法なら、AWS CLI が期限切れを検知して自動で取り直します。
Q. セッション名(role-session-name)には何を入れるとよいですか?
A. 誰が・何のために使っているかがわかる名前にします。セッション名は引き受け後の ARN(assumed-role/ロール名/セッション名)に入り、CloudTrail のログにも残るので、あとから操作を追うときの手がかりになります。
まとめ
- IAMロールは、パスワードやアクセスキーを持たず、引き受けた相手に期限つきの一時的な認証情報を渡す権限の入れ物です。
- 信頼ポリシーは「誰が引き受けられるか」、許可ポリシーは「何ができるか」。Principal があるほうが信頼ポリシーです。
- 流れは
create-role→attach-role-policy→sts assume-role→ 3 つの値を環境変数に設定 →get-caller-identityで確認。 - 設定ファイルに
role_arnとsource_profileを書くと、--profileだけで自動的に切り替わり、期限切れの取り直しも任せられます。 - Principal のキーは相手で変わります(
AWS=アカウント・ユーザー・ロール、Service=AWS サービス、Federated=外部の ID プロバイダー)。 - AssumeRole の AccessDenied は、まず
get-caller-identityで呼び出し元を確かめ、引き受ける側の許可と信頼ポリシーの Principal を順に見ると切り分けられます。 - 同じアカウント内はどちらか一方、別アカウントは両方の許可が必要です。
参考・出典
- AWS Identity and Access Management ユーザーガイド「IAM Identities」 https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html
- 同「AWS JSON policy elements: Principal」 https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html
- 同「Troubleshoot IAM roles」 https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_roles.html
- AWS Security Token Service API リファレンス「AssumeRole」 https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
- 同「Create a role for OpenID Connect federation」 https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html
- 同「Create a role for SAML 2.0 federation」 https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html
- AWS CLI ユーザーガイド「Using an IAM role in the AWS CLI」 https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「IAMロールとは|ユーザー・ポリシーとの違いとAssumeRole、信頼ポリシー」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。