信頼ポリシーでaws:useridを指定したらAssumeRoleに失敗した原因と解決方法

信頼ポリシーでaws:useridを指定したらAssumeRoleに失敗した原因と解決方法

2025.12.14

この記事は アノテーション株式会社 AWS Technical Support Advent Calendar 2025 | Advent Calendar 2025 - Qiita 14日目の記事です。

はじめに

先日、IAM ロールの信頼ポリシーで以下のような設定を見かけました。

信頼ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:userid": [
                        "AROAXXXXXXXXXXXXXXXXX:username1",
                        "AROAXXXXXXXXXXXXXXXXX:username2"
                    ]
                }
            }
        }
    ]
}

Principal でアカウント全体を信頼し、Condition で aws:userid という条件キーにより特定のロールセッションに絞り込む方法を取っているようです。

調べてみると、IAM アイデンティティベースのポリシーを使用して、特定の IAM ロールセッションへのアクセスを制限する方法を教えてください。という記事で、セッション名を使ったアクセス制御の方法として同様の書き方が紹介されていました。

実際にこのような信頼ポリシーを使って AWS CLI を用いたスイッチロールを試したところ、AssumeRole に失敗してしまいました。その後解決できたのでその方法をご紹介します。

結論

スイッチ元のプロファイルに role_session_name を指定すると AssumeRole に成功しました。

ポイント:

  • スイッチ先ではなく、スイッチ元に role_session_name を指定
  • スイッチ先信頼ポリシーの aws:userid で指定したセッション名と一致させる
[profile source-role]
region=ap-northeast-1
source_profile=default
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/SourceRole
role_session_name=[信頼ポリシーで指定したセッション名]  # ← これを設定

aws:userid とは

aws:userid は、IAM エンティティを識別するための一意の ID です。

形式

IAM エンティティには以下のようなプレフィックスがあります:

エンティティ プレフィックス
IAM ユーザー AIDA
IAM ロール AROA
IAM グループ AGPA
マネージドポリシー ANPA
インスタンスプロファイル AIPA
証明書 ASCA

今回のケースではAROAから始まる ID を指定しているため、IAM ロールを条件にしていることが分かります。

Condition での指定方法

AWS 公式ドキュメントでは、aws:useridを使った制御方法として以下の例が示されています:

"Condition": {
    "StringLike": {
      "aws:userId": [
        "AIDACKCEVSQ6C2EXAMPLE",
        "AROADBQP57FF2AEXAMPLE:role-session-name",
        "AROA1234567890EXAMPLE:*",
        "111122223333"
      ]
    }
}

AIDA の場合は ID だけですが、AROA の場合はセッション名まで書く必要があり、以下のパターンで記述できます。

  • 特定のセッション名を指定
  • ワイルドカードで全てのセッション名を指定

今回私が目にしたケースでは特定のセッション名を複数登録しているパターンだったためスイッチロールするには

  • ロール ID が一致している
  • セッション名が username1 または username2

の両方を満たす必要があります。

セッション名

セッション名は、AssumeRole などで発行される一時的な認証情報(セッション)につける識別用の名前です。

AWS CLIでは、role_session_nameを指定しない場合、botocore-session-<UNIXタイム秒>で生成されます[1]:

  • 指定なし:botocore-session-1234567890(自動生成)
  • 指定あり:username1(指定した値)

今回のケースでは、信頼ポリシーで特定のセッション名(username1username2)を指定しているため、スイッチ元のプロファイルでrole_session_nameを明示的に設定する必要があります。

そのため、冒頭で述べたように~/.aws/configで以下のように設定します:

[profile source-role]
region=ap-northeast-1
source_profile=default
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/SourceRole
role_session_name=username1  # ← これを設定

この設定により、SourceRole のセッション名が username1 となり、信頼ポリシーの条件を満たすことができます。

検証環境

今回の検証は、同一の AWS アカウント内でのスイッチロールを想定しています。

作成した IAM ロール

  1. RoleTarget-Principal: Principal でロールのみ直接指定
  2. RoleTarget-UserId: Condition で userid として AROA を指定(セッション名は my-session )
    principal
    userid

AWS CLI設定
~/.aws/config の設定を変更しました。以下の検証ができるようにプロファイルを作成しています。

  1. スイッチ元で role_session_name=my-session を設定して RoleTarget-Principal にスイッチロール
  2. スイッチ元で role_session_name=my-session を設定せずに RoleTarget-Principal にスイッチロール
  3. スイッチ元で role_session_name=my-session を設定して RoleTarget-UserId にスイッチロール
  4. スイッチ元で role_session_name=my-session を設定せずに RoleTarget-UserId にスイッチロール

検証 3 と検証 4 が今回の検証の本質で、検証 1 と検証 2 はおまけとして Principal でロールを直接指定をしている場合にセッション名が影響するか確認しています。

~/.aws/config の設定
# スイッチ元(セッション名指定あり)
[profile source-mysession]
region=ap-northeast-1
source_profile=classmethod
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/SourceRole
role_session_name=my-session  # ← 指定
mfa_serial=arn:aws:iam::yyyyyyyyyyyy:mfa/your-mfa

# スイッチ元(セッション名指定なし)
[profile source-autogen]
region=ap-northeast-1
source_profile=classmethod
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/SourceRole
mfa_serial=arn:aws:iam::yyyyyyyyyyyy:mfa/your-mfa

# Test 1: Principal(my-session)
[profile test1-principal-mysession]
source_profile=source-mysession
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/RoleTarget-Principal

# Test 2: Principal(自動生成)
[profile test2-principal-autogen]
source_profile=source-autogen
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/RoleTarget-Principal

# Test 3: UserId(my-session)
[profile test3-userid-mysession]
source_profile=source-mysession
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/RoleTarget-UserId

# Test 4: UserId(自動生成)
[profile test4-userid-autogen]
source_profile=source-autogen
role_arn=arn:aws:iam::xxxxxxxxxxxx:role/RoleTarget-UserId

検証

キャッシュが残ってしまうと結果が変わってしまうため、毎回キャッシュのクリアを挟んでいます。

  1. スイッチ元で role_session_name=my-session を設定して RoleTarget-Principal にスイッチロール
    1

  2. スイッチ元で role_session_name=my-session を設定せずに RoleTarget-Principal にスイッチロール
    2

  3. スイッチ元で role_session_name=my-session を設定して RoleTarget-UserId にスイッチロール
    3

  4. スイッチ元で role_session_name=my-session を設定せずに RoleTarget-UserId にスイッチロール
    4

4 のテストのみスイッチロールできませんでした(想定通り)

botocore-session-XXX... is not authorized to perform: sts:AssumeRole on resource:
とあり、スイッチ元のセッション名を指定しなかったためセッション名がbotocore-session-<UNIXタイム秒>となってしまっているため弾かれているようですね。

ちなみに ~/.aws/config ファイルで role_session_name=tanaka など、あえて失敗するようなセッション名を指定した場合、同様に
tanaka is not authorized to perform: sts:AssumeRole on resource:
と表示されました。

分かったこと

  1. Principal でロールを直接指定の場合:
  • どんなセッション名でも成功する
"Principal": {
  "AWS": "arn:aws:iam::XXXXXXXXXXXX:role/ロール名"

ここではロールの ARN で指定しているため、そのロールであればどのセッション名でも AssumeRole に成功します。

  1. userid でロールを指定した場合:
  • スイッチ元のセッション名をスイッチ先の信頼ポリシーで指定したセッション名と一致しないとスイッチロールに失敗する
  • role_session_name を指定しないと実質的にランダムなセッション名が生成される
"Condition": {
    "StringEquals": {
        "aws:userid": "AROAXXXXXXXXXXXXXXXXX:my-session"
    }
}

ここではロール ID とセッション名(my-session)の両方を指定しているため、両方が一致する必要があります。

おわりに

同様の問題でスイッチロールできなかった際に、解決策の1つとしてお試しいただけると幸いです。

参考

[1] botocore/botocore/credentials.py at 1.19.4 · boto/botocore

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。

この記事をシェアする

FacebookHatena blogX

関連記事