aws loginでスイッチロールを試してみる

aws loginでスイッチロールを試してみる

2026.04.01

はじめに

こんにちは。コンサルティング部の津谷です。
今回は2025年11月に登場したaws loginについて検証してみます。

aws loginとは

ローカル上でAWS認証を行うサービスになります。AWS CLIを利用する場合は、クレデンシャル情報(アクセストークン)を「/.aws/credentials」に登録する必要がありました。シークレット情報をローカルで平文保管するとセキュリティ的に危険です。ローカルPCがマルウェアに感染したりすると、キーファイルの漏洩によって関連するアカウントへ侵入され情報漏洩があるといったケースもあるかと思います。これを避けるべく、いくつか選択肢があります。

  • aws vaultなどのキー管理のサードパーティを利用したりする方法です。aws vaultの場合は認証情報をOSのキーストアに保管し、 認証時は一時的なSTSによるトークン認証を実行します。詳細は以下のブログが参考になるのでご参照ください。

https://dev.classmethod.jp/articles/aws-vault/

  • IAM Identity Centerを利用していればsso認証でスイッチさせることもでき、クレデンシャルを保管せずに安全に運用することも可能です。こちらも詳細はブログをご参照ください。

https://dev.classmethod.jp/articles/aws-cli-for-iam-identity-center-sso/

2025年11月のアップデートでは、ブラウザベースでAWSログイン認証を行うことで、セッション情報をCLI上で取得できるようになりました。IAMユーザを使った認証を行う場合にもクレデンシャルの永久保存をすることなく安全にアクセスが可能になります。
https://aws.amazon.com/jp/blogs/news/simplified-developer-access-to-aws-with-aws-login/

新機能では、従来のOAuth2.0による認可コードフローに加えてPKCE認可フローを採用しています。ここでは詳細には触れませんが、以前にネイティブアプリでcode_verifierの生成や、ハッシュ化したcode_challengeを用いた認可コードの保護については、ネイティブアプリによるJWT検証でも触っていますのでそちらもブログもご参照ください。

https://dev.classmethod.jp/articles/alb-jwt/

以下のブログでもaws loginの基本的な利用方法をわかりやすくされているので、ぜひご参照ください。
https://dev.classmethod.jp/articles/aws-cli-aws-login/

実用的に利用するケース

aws loginを実運用していく中で以下のケースが多いかと思います。

  • JumpアカウントでIAMユーザとしてログインした後、別アカウント(または同じアカウント)内で別ロールにスイッチするケース
  • スタンドアロンアカウント内で、IAMユーザとしてログインした後、同アカウント内の別ロールにスイッチするケース
  • 上記を実現するうえで、スイッチ元の信頼関係でMFAを強制しているようなケース

上記のケースを検証するとともに、おまけでTerraformなどの外部サービスが認証を引き受ける方法についても調査してみます。

準備

基本的なところから始めていきます。

まずは以下を作成しましょう。(コンソールでの作成は割愛します)

  • IAMユーザ(アカウントA側)
    • MFAを有効化しておきましょう。今回の検証ではスイッチ元はMFAを強制するためです。
  • スイッチ先となるIAMロール
    • アカウントAに1つ
    • アカウントBに1つ

スイッチ先のロールについては、信頼ポリシーを以下のように設定しました。
【アカウントAのロール】

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<アカウントA>:user/<IAMユーザ名>"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}

【アカウントBのロール】

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<アカウントB>:user/<IAMユーザ名>"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}

許可ポリシーは検証なので、PowerUserAccessを付与しています。

IAMユーザ側にも、ロールA・ロールBにAssumeRoleできる権限を付与しておきます。

{
"Version": "2012-10-17",
"Statement": [
	{
		"Effect": "Allow",
		"Action": "sts:AssumeRole",
		"Resource": [
			"arn:aws:iam::<アカウントA>:role/<ロールA>",
			"arn:aws:iam::<アカウントB>:role/<ロールB>"
		]
	}
]
}

次はCLI上の設定をしていきます。
AWS CLIは以下から事前にインストールしてください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
バージョン制約は「v.2.32.0」以降なので、aws --versionコマンドで確認しておきましょう。

エディタで設定をしていきます。
/.aws/credential上にアクセストークンを入れる必要はなく、/.aws/config上にプロファイルの設定をしていく形になります。aws login実行時もプロファイルを指定して認証することになります。

以下を入力して、編集していきます。

vi ~/.aws/config

自分は以下のように記載しました。

[profile <IAMユーザ>]
region = ap-northeast-1

[profile <ロールA>]
region = ap-northeast-1
source_profile = <IAMユーザ>
role_arn = arn:aws:iam::<アカウントA>:role/<ロールA>

[profile <ロールB>]
region = ap-northeast-1
source_profile = <IAMユーザ>
role_arn = arn:aws:iam::<アカウントB>:role/<ロールB>

一番上のプロファイルが最初にログインするIAMユーザのプロファイルになります。指定するのはリージョンのみでOKです。真ん中がロールAのプロファイルです。こちらのロールはIAMユーザと同じアカウントにあります。同様にリージョンを指定しますが、source_profileの指定が必要になります。この変数はどのIAMユーザからスイッチするのかを指定する情報になります。そのため今回作成したIAMユーザ名を指定します。それ以外のユーザからはCLI上でスイッチすることはできません。ロール情報(arn情報)はrole_arnで指定します。一番下はロールBのプロファイルで、IAMユーザとは別アカウントにあります。記載観点はロールAと同じになります。

aws loginしてみる

準備ができたので、aws login実行していきます。

aws login --profile <IAMユーザ名>

プロファイル指定をしないと、defaultプロファイルが選択されます。こちらでもアクセス自体はできるのですが、基本的には用途に応じてプロファイルは分けておくのを推奨します。どのユーザで認証しているのか、プロファイルを確認してもわからなくなり、意図しないアカウントへの操作を未然に防ぐという観点があるかと思います。

ブラウザリンクが出力されるので(ctrl+Enter)で開きます。
スクリーンショット 2026-03-19 100620

すでにAWSアカウントにサインインしている場合は、ユーザ・ロールが出力されます。例えば、IAMユーザAでコンソールにアクセスしていればIAMユーザAの認証情報をそのままCLIで利用できるということです。

今回は検証もかねて「新しいセッションにサインイン」を選択しました。

スクリーンショット 2026-03-19 100925

そうすると、「ルートまたはIAMユーザで続行」と出力されるので、こちらをクリックします。
ユーザサインイン画面に移動するので、今回は作成したIAMユーザの情報でログインしていきます。
今回はMFA入力があるので、そちらも入力しておきます。

スクリーンショット 2026-03-19 101213
ログインに成功すると上記のような画面に遷移し、セッション情報の取得に成功したことがわかります。

CLIに戻ってみると、以下のように出力されていました。

Updated profile <IAMユーザ> to use arn:aws:iam::<アカウントA>:user/<IAMユーザ> credentials.
Use "--profile <IAMユーザ>" to use the new credentials, such as "aws sts get-caller-identity --profile <IAMユーザ>"

これでログイン自体に成功したので、profile情報を確認してみましょう。

cat ~/.aws/config

login_session情報が追加されていますね。

[profile <IAMユーザ>]
region = ap-northeast-1
login_session = arn:aws:iam::<アカウントA>:user/<IAMユーザ>

ここには、認証したIAMユーザのarn情報が記載されます。一時トークンの情報は/.aws/login/cacheに保存されています。Identity CenterでのSSO認証の場合は/.aws/sso/cacheに保管されていました。中身を見るとわかるのですが、JSON形式で平文保存されています。キャッシュの保管期間は15分なのでそれ以降は問題ないですが、よりセキュリティ対策を厳格にするのであれば、ローカルでパーミッション設定等でアクセス権限を絞るといったこともやっておくと良さそうです。

それでは、実際にスイッチ先ロールでSTSトークンの引き受けができるのか確認してみます。

【ロールA】

aws --profile <ロールAのプロファイル名> sts get caller-identity

{
  "UserId": "xxxx:botocore-session-xxxx",
  "Account": "<アカウントA>",
  "Arn": "arn:aws:sts::<アカウントA>:assumed-role/<ロールA>/botocore-session-xxxx"
}

【ロールB】

aws --profile <ロールBのプロファイル名> sts get caller-identity

{
  "UserId": "xxxx:botocore-session-xxxx",
  "Account": "<アカウントB>",
  "Arn": "arn:aws:sts::<アカウントB>:assumed-role/<ロールA>/botocore-session-xxxx"
}

スイッチできていますね。従来はmfa認証を行う場合は以下をプロファイルに指定する必要がありました。

mfa_serial = arn:aws:iam::<アカウントID>:mfa/<IAMユーザ名>

aws loginで認証を行う場合は、ブラウザ上で一度MFA認証を実施すれば、以下のようにCLI上でパスコードの入力を求められません。
スクリーンショット 2026-03-19 121902

1つ仕様の話をします。自分も引っかかったのですが、ブラウザでIAM認証をした後にaws loginを実行すると以下のエラーが起きます。

aws login --profile <ロールAのプロファイル名>

Profile '<ロールAのプロファイル名>' is already configured with Assume Role credentials.

You may run 'aws login --profile new-profile-name' to create a new profile with the     specified name. Otherwise you must first manually remove the existing credentials from '<ロールAのプロファイル名>'.

すでに、プロファイル名は認証されているというエラーです。aws loginでIAMユーザで認証を行っているため、--profileでプロファイルを指定するだけで、CLIコマンドをそのプロファイル情報で実行できるという話です。そのため、改めてaws loginを実行する必要はございません。

例外ケース

基本的にスイッチ先ロールの権限を使ってCLIコマンドによるAWS APIコールができるようになりますが、現時点だと制約があるケースも存在しています。

例えばTerraformに認証情報を渡して、applyする際は上記のプロファイル設定ではうまくいきません。
試してみました。ロールAのプロファイル情報を使ってterraform planをしてみました。

terraform init
AWS_PROFILE=<ロールAのプロファイル名>
terraform plan

terraform planを走らせたタイミングでAWS API経由でリソース情報を取りに行きます。その際に以下のエラーがでました。

│ Error: failed to load assume role arn:aws:iam::<アカウントA>:role/<ロールA>, of profile <IAMユーザ>, <nil>
│ 
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on provider.tf line 12, in provider "aws":
│   12: provider "aws" {

プロファイル情報が正常にロードしていないことがわかります。これは、~/.aws/login/cacheをTerraform側で読みに行けないためです。

【補足】
Terraformでは、plan/apply等でAWS APIにアクセスする必要があります。これを仲介しているのがAWS Providerになります。AWS ProviderはAWS SDK for Go v2を内部ライブラリとして使っていることがコードレベルで確認されています。
https://github.com/hashicorp/terraform-provider-aws/blob/main/go.mod

バージョンはv1.41.4を利用しており、v1.40.0以降のSDK経由での認証も.aws/login/cacheに対応しています。
【リリース情報】
https://newreleases.io/project/github/aws/aws-sdk-go-v2/release/release-2025-11-19.2
【公式ドキュメント】
https://docs.aws.amazon.com/sdkref/latest/guide/feature-login-credentials.html

AWS Provider側ではaws-sdk-go-baseという認証周りのコア機能となるライブラリを利用していますが、こちらがcacheの読み取り機能に追従していないものと考えられます。このあたりの内容は改善がくることを祈っております。

一旦回避策として以下のようにプロファイルを書き換えてみました。

[profile <IAMユーザ>]
region = ap-northeast-1
login_session = arn:aws:iam::<アカウントA>:user/<IAMユーザ>

[profile <IAMユーザ>-tf]
region = ap-northeast-1
credential_process = aws configure export-credentials --profile <IAMユーザ> --format process

[profile <IAMロールA>-tf]
region = ap-northeast-1
source_profile = <IAMユーザ>-tf
role_arn = arn:aws:iam::<アカウントA>:role/<ロールA>

credential_processを使うことで、IAMユーザの認証セッション情報を取得することが可能です。
以下のブログでわかりやすく説明してくれているので、ご参照ください。
https://dev.classmethod.jp/articles/aws-cli-credential_process-assume-role/

このプロファイルは別に作成しておきました。実際にterraform plan/applyを実行するロールは<IAMロールA>-tfになります。source_profileを指定することで、実行ができるようになります。

プロファイルを環境変数に指定して、terraform applyすると正常に作られそうです。

Plan: 4 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + bucket_arn         = (known after apply)
  + bucket_domain_name = (known after apply)
  + bucket_id          = (known after apply)

applyを実行すると正常にリソースが作成されました。

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Outputs:

bucket_arn = "arn:aws:s3:::<バケット名>"
bucket_domain_name = "<バケット名>.s3.amazonaws.com"
bucket_id = "<バケット名>"

さいごに

aws loginはアクセスキーをローカルに保管することなく、短時間でのセッション取得が可能なので、セキュリティ面の向上が期待できます。
すでに多くの方が試されていますが、スイッチロールによる権限分離やterraformを使ったIaC管理でロール引き受けするといった実用的な利用方法もこれから実践していきたいところです。

この記事をシェアする

関連記事