aws sts get-caller-identityは、いまのAWS CLIが「誰として」「どのアカウントに」接続しているかを返すコマンドです。プロファイルを切り替えた直後、SSOでログインした直後、CIでロールを引き受けた直後に1回打てば、意図しないアカウントへの操作を実行前に止められます。この記事は、出力されるUserId・Account・Arnの読み方、ARNの形から認証元を見分ける方法、権限が不要という仕様の落とし穴、エラー別の直し方、デプロイ前のガードに組み込む実装例を、AWS公式ドキュメント(2026年10月時点のCLIリファレンス表記は2.37.9)に沿って整理した内容です。CLIの導入そのものはAWS CLIのインストールと運用|OS別の導入手順・v2の設定・SSO認証・v1サポート終了への移行で扱っています。
まとめ|aws sts get-caller-identityで確かめられることと使いどころ
先に結論です。このコマンドで押さえておきたいのは次の5点です。
- 返るのはUserId・Account・Arnの3項目だけで、追加のIAM権限は要らない
- Arnが
user/ならIAMユーザー、assumed-role/ならロールの一時認証情報、ロール名がAWSReservedSSO_で始まればIAM Identity Center経由 - 成功しても「認証が通った」ことしか分からない。S3やEC2を操作する権限があるかは別に確かめる
- 想定外のアカウントが返ったら、環境変数が設定ファイルより優先される読み込み順を疑う
- デプロイやTerraformの実行前に
--query Account --output textで照合すれば、本番と検証の取り違えを機械的に止められる
以降では、それぞれをコマンド付きで手順に落とします。
aws sts get-caller-identityの実行手順と出力される3項目の読み方
前提はAWS CLI v2が入り、何らかの認証情報が設定されている状態です。
AWS CLI v2で実行して返るUserId・Account・Arnの意味と役割
CLIリファレンスの例と同じく、引数なしで実行します。
aws sts get-caller-identity
{
"UserId": "AIDASAMPLEUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/DevAdmin"
}
APIリファレンスの定義では、Accountは呼び出し元を所有するAWSアカウントID、Arnは呼び出し元に結び付いたARN、UserIdは呼び出し元の一意な識別子です。UserIdの値は呼び出し元の種類で形が変わり、IAMポリシー変数aws:useridと同じ値が入ります。
別のプロファイルで確かめたいときは--profileを付けます。aws sts get-caller-identity --profile stagingのように、切り替えた先が本当に検証環境のアカウントかをその場で確認できます。
–queryと–output textでアカウントIDだけを取り出すコマンド
スクリプトで使うときは、JSON全体ではなく必要な値だけを文字列で取り出します。--queryはJMESPath式で出力を絞るグローバルオプションです。
# アカウントIDだけを取り出す
aws sts get-caller-identity --query Account --output text
# 123456789012
# ARNだけを取り出す
aws sts get-caller-identity --query Arn --output text
# 2項目をタブ区切りで取り出す
aws sts get-caller-identity --query "[Account, Arn]" --output text
--output textを付けないと値がダブルクォートで囲まれ、文字列比較が一致しなくなります。シェル変数に入れる用途では必ず付けてください。
ArnとUserIdの形で判別するIAMユーザー・ロール・SSOの認証元
このコマンドの本当の使いどころは、アカウントIDよりもArnとUserIdの「形」を読むことにあります。
ARNの形式4種類からCLIで今使っている認証元を見分ける対応表
IAM識別子のドキュメントにあるARNの書式を、get-caller-identityで返りうる形に絞って表にしました。
| Arnの形 | 認証元 |
|---|---|
| iam::<ID>:root | ルートユーザー |
| iam::ID:user/名前 | IAMユーザーの長期キー |
| sts::ID:assumed-role/… | ロールの一時認証情報 |
| sts::ID:federated-user/… | GetFederationToken |
表中のIDはアカウントID、名前はIAMユーザー名を表すプレースホルダーです。各行の表記はARNの識別に使う部分を示し、「…」は後続部分の省略を表しています。assumed-roleの後ろは「ロール名/ロールセッション名」の2段です。IAM Identity Centerでログインした場合、ロール名は権限セットから自動作成されたAWSReservedSSO_<権限セット名>_<英数字>になり、セッション名にはサインインしたユーザー名が入ります。rootが返ったら、日常作業をルートユーザーで行っている状態なので、すぐに切り替えを検討してください。SSOの権限セット設計はAWS IAM Identity Centerとは?権限セット設計とCLI認証・IAMとの使い分けを実装者目線で解説にまとめています。
UserIdのAIDA・AROAプレフィックスとロールセッション名の読み方
同じドキュメントの一意IDのプレフィックス表では、AIDAがIAMユーザー、AROAがロール、AKIAが長期アクセスキー、ASIAがSTSの一時アクセスキーです。ロールを引き受けている場合、UserIdはAROA…:セッション名のようにロールの一意IDとセッション名をコロンでつないだ形になります。GetFederationTokenの場合はアカウントID:フェデレーションユーザー名です。
一意IDは、同名のIAMユーザーを削除して作り直すと別の値になります。退職者と同じ名前の新規ユーザーを見分けたいとき、名前ではなくUserIdで照合すれば取り違えません。
権限不要と明示的Denyでも成功する仕様から分かる確認範囲の限界
get-caller-identityは、ほかのAWS APIと権限の扱いが違います。
Denyポリシーを付けても止められない理由と権限確認には使えない点
APIリファレンスには「この操作に権限は不要で、管理者がsts:GetCallerIdentityを明示的に拒否するポリシーを付けても実行できる」と書かれています。理由は、アクセス拒否のエラーメッセージにも同じ情報が含まれるためです。
ここから分かるのは、成功は「署名が有効な認証情報を持っている」ことの証明にとどまるという点です。s3:PutObjectやec2:RunInstancesを実行できるかは何も保証しません。「get-caller-identityが通ったのにS3でAccessDeniedになる」のは正常な挙動で、原因はポリシー側にあります。権限の組み立てはAWS IAMとは?仕組み・ユーザー/ロール/ポリシーの違いと権限設計のベストプラクティスを実装者目線で解説を参照してください。
GetAccessKeyInfoで漏えいしたアクセスキーの所属アカウントを調べる手順
手元に認証情報は無いが、ログやリポジトリで見つけたアクセスキーIDがどのアカウントのものか知りたい。そんな場面では、get-caller-identityではなくGetAccessKeyInfoを使います。
aws sts get-access-key-info --access-key-id AKIAI44QH8DHBEXAMPLE --query Account --output text
返るのはアカウントIDだけで、キーが有効か無効か、削除済みかは分かりません。AKIAで始まればIAMユーザーかルートユーザーの長期キー、ASIAならSTSの一時キーです。自社アカウントのものだった場合は、認証情報レポートで持ち主のIAMユーザーを特定し、ASIAならCloudTrailのSTSイベントで発行元をたどる、という順番がドキュメントに示されています。
想定と違うアカウントが返るときの認証情報の優先順位と切り分け
「検証環境のつもりが本番のアカウントIDが返った」というずれは、ほぼ認証情報の読み込み順で説明できます。
環境変数が設定ファイルより優先される認証情報の10段階の読み込み順序
CLIの設定ドキュメントに載っている優先順位は、上から次の10段階です。
- コマンドラインオプション(
--profileなど) - 環境変数
- ロールの引き受け(assume role)
- ウェブIDによるロールの引き受け
- IAM Identity Center
- credentialsファイル
- 外部プロセス(credential_process)
- configファイル
- コンテナの認証情報(ECSタスクロール)
- EC2インスタンスプロファイル
実務で一番多いのは2番の取り残しです。以前のシェルでexport AWS_ACCESS_KEY_ID=…を実行したまま、AWS_PROFILEだけを切り替えても、キーの環境変数が残っていればそちらが使われます。EC2上で想定外のロールが返る場合は、設定ファイルが無いため10番のインスタンスプロファイルまで落ちている可能性が高いでしょう。
aws configure listで認証情報の出どころを特定するコマンド
どの段階から読まれたかはaws configure listで確認できます。値の取得元(TYPE)と場所(LOCATION)が項目ごとに出ます。
aws configure list
NAME : VALUE : TYPE : LOCATION
profile : <not set> : None : None
access_key : ****************ABCD : env : AWS_ACCESS_KEY_ID
secret_key : ****************ABCD : env : AWS_SECRET_ACCESS_KEY
region : ap-northeast-1 : config_file : ~/.aws/config
# 残っている環境変数を消してから確かめ直す(bash)
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
aws sts get-caller-identity --profile staging
TYPEがenvなら環境変数が勝っています。unsetしてから--profile付きで打ち直し、Accountが変わるかを見れば切り分けは終わりです。ロールの切り替えを頻繁に行うなら、AWSume(オースム)とは?AWS認証情報とIAMロール切替を効率化するCLIツールのような専用ツールで環境変数の出し入れを任せる手もあります。
エラーメッセージ別に見るget-caller-identityが失敗する原因と直し方
このコマンド自体に権限は要らないため、失敗の原因は認証情報か通信のどちらかに絞れます。
Unable to locate credentialsと終了コード253への対処
Unable to locate credentialsは、10段階のどこからも認証情報が見つからなかったことを意味します。終了コードのドキュメントでは、設定や認証情報が無い場合の終了コードは253です。
確認の順番は、aws configure listでprofileが意図した名前か、~/.aws/configにそのプロファイルが存在するか、の2点です。SSOを使うプロファイルならaws sso login --profile 名前を先に実行します。マネジメントコンソールの認証情報をそのまま使うaws login(CLI 2.32.0以降)を使う場合の手順はaws loginコマンドの実行手順とsso login・アクセスキーとの使い分けにあります。
ExpiredToken・InvalidClientTokenId・署名エラーの判別表
認証情報は見つかったがAWS側で拒否された場合は、サービスがエラーを返したことを示す終了コード254になります。エラーコードごとの原因は次の通りです。
| エラーコード | 主な原因 |
|---|---|
| ExpiredToken | 一時認証情報の期限切れ |
| InvalidClientTokenId | キーIDの誤りか削除済み |
| SignatureDoesNotMatch | シークレットキーの誤り |
| 署名期限切れ(Signature expired) | 端末の時刻ずれ |
ExpiredTokenは、環境変数に古いAWS_SESSION_TOKENが残っているときにも出ます。解消するための操作は、SSOなら再ログイン、ロールなら引き受け直しです。時刻ずれについては、CLIの設定ドキュメントに「署名には日時が含まれ、端末の時刻がAWS側と大きくずれるとリクエストが拒否される」と明記されています。仮想マシンやWSLをスリープから戻した直後に起きやすいので、NTPで時刻を合わせてから再実行してください。
STSのリージョナルエンドポイントとグローバルエンドポイントの既定値の違い
get-caller-identityはどのリージョンでも同じ結果を返しますが、問い合わせ先のエンドポイントはCLIとSDKで既定値が違います。閉域網やプロキシ越しの環境では、ここが疎通の可否を分けます。
CLI v2はリージョナル・CLI v1とboto3はグローバルが既定となる差
SDKとツールのリファレンスの対応表では、AWS CLI v2は設定したリージョンのエンドポイント(例:sts.ap-northeast-1.amazonaws.com)が既定です。一方、AWS CLI v1はlegacyが既定でグローバルのsts.amazonaws.comへ、boto3は設定値の既定こそregionalですが、クライアントの既定の向き先はグローバルエンドポイントと記載されています。
# ~/.aws/config(CLI v1・boto3など設定に対応するSDK向け)
[profile app]
region = ap-northeast-1
sts_regional_endpoints = regional
# 環境変数で指定する場合
export AWS_STS_REGIONAL_ENDPOINTS=regional
VPCエンドポイント(PrivateLink)でSTSに出る構成では、CLI v2では通るのにアプリのboto3だけがタイムアウトする、というずれがこの既定値の差から生まれます。同じ表で、CLI v2にはこの設定自体が無いことも確認できます。
グローバルエンドポイントの処理リージョン変更とCloudTrailの記録先
IAMユーザーガイドのSTSエンドポイントのページによると、以前はグローバルエンドポイントへのリクエストをすべてバージニア北部(us-east-1)で処理していました。現在は、既定で有効なリージョンからAmazonのDNSで名前解決したリクエストは、送信元と同じリージョンで処理されます。オプトインリージョンからのリクエストや、ISPや公開DNSで解決した場合は、従来どおりus-east-1です。
ただしCloudTrailの記録先は変わらず、グローバルエンドポイント宛てのイベントはus-east-1に残ります。東京リージョンだけを監視していると、get-caller-identityを含むSTSの呼び出しが見えません。条件キーaws:RequestedRegionの値もus-east-1のままなので、リージョン制限のSCPを書くときは、除外するグローバルサービスにSTSも含めておかないと、グローバルエンドポイント経由の呼び出しまで拒否されます。
デプロイ前の誤爆防止にget-caller-identityを組み込む実装例
ここからは、確認を人の目に頼らず、スクリプトやCIで機械的に止める書き方です。
シェルスクリプトで想定外のアカウントIDなら即停止するガード処理
本番用と検証用でスクリプトを共有しているなら、冒頭で想定アカウントと照合します。
#!/usr/bin/env bash
set -euo pipefail
EXPECTED_ACCOUNT="${EXPECTED_ACCOUNT:?想定アカウントIDを指定してください}"
actual="$(aws sts get-caller-identity --query Account --output text)"
if [ "$actual" != "$EXPECTED_ACCOUNT" ]; then
echo "想定外のAWSアカウントです: ${actual}(想定: ${EXPECTED_ACCOUNT})" >&2
exit 1
fi
echo "アカウント確認OK: ${actual}"
# ここから先にデプロイ処理を書く
set -eを付けているため、認証情報が無い場合も終了コード253でその場で止まります。EXPECTED_ACCOUNT=123456789012 ./deploy.shのように呼び出し側で値を渡せば、環境ごとにスクリプトを分けずに済みます。
boto3とTerraformのaws_caller_identityによる照合例
Pythonのバッチではboto3のget_caller_identityが同じ3項目を辞書で返します。
import boto3
EXPECTED_ACCOUNT = "123456789012"
sts = boto3.client("sts", region_name="ap-northeast-1")
ident = sts.get_caller_identity()
if ident["Account"] != EXPECTED_ACCOUNT:
raise SystemExit(f"想定外のアカウントです: {ident['Account']} ({ident['Arn']})")
Terraformではaws_caller_identityデータソースがaccount_id・arn・user_idを返します。preconditionと組み合わせると、planの段階で止められます。
data "aws_caller_identity" "current" {}
variable "expected_account_id" {
type = string
}
resource "terraform_data" "account_guard" {
lifecycle {
precondition {
condition = data.aws_caller_identity.current.account_id == var.expected_account_id
error_message = "想定外のAWSアカウントに対してplanを実行しようとしています。"
}
}
}
バケット名などにdata.aws_caller_identity.current.account_idを埋め込めば、アカウントIDを変数ファイルに直書きせずに済みます。
GitHub ActionsのOIDC認証直後に引き受けたロールを検証するステップ
CIでは、OIDCでロールを引き受けた直後に、ArnがARNの想定パターンに一致するかを確かめます。
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::123456789012:role/github-deploy
aws-region: ap-northeast-1
- name: 引き受けたロールを確認する
run: |
arn="$(aws sts get-caller-identity --query Arn --output text)"
case "$arn" in
arn:aws:sts::123456789012:assumed-role/github-deploy/*) echo "OK: $arn" ;;
*) echo "想定外のロールです: $arn"; exit 1 ;;
esac
ロールのARN(iam::…:role/)と、引き受けた後のARN(sts::…:assumed-role/)は形が違う点に注意してください。role-to-assumeの値をそのまま比較しても一致しません。OIDCの信頼ポリシーやsubの不一致エラーはconfigure-aws-credentialsの使い方:OIDC設定とv6の変更点、sub不一致エラーの直し方で解説しています。
get-caller-identityで済ませる確認と別の手段に任せる確認の線引き
最後に、このコマンドに頼ってよい範囲と頼ってはいけない範囲を言い切っておきます。
実行前チェックに使う場面と権限検証に使ってはいけない3つの場面
使うべき場面は「どのアカウントに、誰として入っているか」を確かめる場面だけです。プロファイルを切り替えた直後、デプロイやTerraformの実行前、CIでロールを引き受けた直後の3か所には、毎回入れておく価値があります。権限を追加で付ける必要が無く、既存のIAM設計にも影響しません。
使ってはいけない場面もはっきりしています。1つ目は権限の確認です。成功しても操作権限は保証されないため、必要な権限はEC2のように--dry-runを持つAPIで試すか、IAMポリシーシミュレーターで確かめます。2つ目は接続確認の代わりです。STSが応答しても、閉域網やプロキシの設定次第で対象サービスのエンドポイントに届くとは限りません。3つ目は、Denyポリシーでこの呼び出しを封じてアカウントIDを隠そうとする設計です。仕様上止められないため、漏えいしたキーの有効性を第三者が試す手段にもなります。CloudTrailでGetCallerIdentityが見慣れない送信元から続けて呼ばれていたら、キー漏えいを疑うきっかけにしてください。
複数アカウントの認証設計やCIの権限分離を含めてAWS環境を整えたい場合は、インフラ構築(AWS・Google Cloud・Azure)で要件整理から対応しています。
よくある質問
aws sts get-caller-identityについて検索されている質問に、公式ドキュメントの記載をもとに答えます。
aws sts get-caller-identityを実行するのにIAM権限は必要ですか?
必要ありません。APIリファレンスには、sts:GetCallerIdentityを明示的に拒否するポリシーを付けても実行できると書かれています。アクセス拒否のエラーにも同じ情報が含まれるため、拒否する意味が無いという理由です。そのため、成功しても他のAWSサービスを操作する権限があることの証明にはなりません。
get-caller-identityでAWSアカウントIDだけを取得するにはどうすればよいですか?
aws sts get-caller-identity --query Account --output textを実行します。--output textを省くとダブルクォート付きの文字列になり、シェルで比較したときに一致しません。プロファイルを指定する場合は--profile 名前を足してください。
get-caller-identityのArnにassumed-roleと出るのはどういう状態ですか?
IAMロールを引き受けて発行された一時認証情報で接続している状態です。assumed-role/ロール名/セッション名の形で表示され、IAM Identity Centerでログインした場合はロール名がAWSReservedSSO_で始まります。UserIdはAROAで始まるロールの一意IDとセッション名をコロンでつないだ値です。
プロファイルを切り替えたのに同じアカウントが返るのはなぜですか?
環境変数のAWS_ACCESS_KEY_IDなどが残っていると、設定ファイルのプロファイルより優先されます。aws configure listでTYPEがenvになっていないかを確認し、該当する環境変数をunsetしてから再実行してください。--profileオプションを明示した場合はコマンドラインが最優先になります。
Pythonのboto3で同じ情報を取得できますか?
できます。boto3.client("sts").get_caller_identity()がUserId・Account・Arnを含む辞書を返します。boto3はSTSの問い合わせ先がCLI v2と異なり、既定でグローバルエンドポイントに向くことがあるため、閉域網で使う場合はsts_regional_endpoints = regionalとリージョンの指定を設定ファイルに入れておくと確実です。
関連記事
- AWS CLIのインストールと運用|OS別の導入手順・v2の設定・SSO認証・v1サポート終了への移行:本記事のコマンドを動かす前段の環境構築。
- AWS IAM Identity Centerとは?権限セット設計とCLI認証・IAMとの使い分けを実装者目線で解説:AWSReservedSSO_ロールを生む権限セットの設計。
- aws loginコマンドの実行手順とsso login・アクセスキーとの使い分け:認証情報を用意する3つの方法の比較。
- AWS IAMとは?仕組み・ユーザー/ロール/ポリシーの違いと権限設計のベストプラクティスを実装者目線で解説:get-caller-identityでは分からない操作権限の組み立て。
- configure-aws-credentialsの使い方:OIDC設定とv6の変更点、sub不一致エラーの直し方:CIでロールを引き受ける側の設定。