What does the `aws sts get-caller-identity` command return, and how do you read the ARN it prints when the caller is using an assumed role?
answer
- the who-am-I call
- three fields: account, user ID, ARN
- sts ARN, not the iam one
- two segments after assumed-role
- no permission needed to call it
basics
~20 sIt returns the Account, UserId and Arn that AWS attributes to the credentials just used. For a role session the Arn has the form arn:aws:sts::<account>:assumed-role/<RoleName>/<SessionName>, naming the role and the session rather than any user.
solid answer
~50 s`aws sts get-caller-identity` is the "who am I" call: it echoes back the account ID, the unique `UserId`, and the ARN AWS resolved from whatever credentials signed the request. It is the first thing to run when something is denied, because it tells you whether you are the identity you think you are. Two details matter. First, it requires no IAM permissions at all — an explicit deny on `sts:GetCallerIdentity` does not stop it, since the same information comes back either way, so it always works as a diagnostic. Second, the ARN for a role session is an **STS** ARN, `arn:aws:sts::111122223333:assumed-role/AppRole/session-name`, and that is not the ARN you write into policies. When you need to name the identity as a `Principal` in a bucket policy or a trust policy, use the IAM role ARN, `arn:aws:iam::111122223333:role/AppRole`. The session-name half of the STS ARN is your audit handle: it is what distinguishes one caller from another in CloudTrail.
go deeper
Know the command exists and what its three fields mean, and make it your reflex first step whenever an AWS call is denied or you are unsure which profile is active.
Be able to parse the ARN: service sts, then role name and session name. Explain why the IAM role ARN, not the session ARN, is what goes into a policy's Principal.
Use it as a diagnostic discipline — confirm identity and account before touching policy — and enforce meaningful session names so CloudTrail can attribute actions on a shared role.
Set the convention: what session names must encode across humans and pipelines, whether it is enforced by a trust-policy condition, and how that convention feeds investigation and access review.
## The one command that answers "who am I" ```bash aws sts get-caller-identity ``` ```json { "UserId": "AROAEXAMPLEID:batch-2026-08-21", "Account": "111122223333", "Arn": "arn:aws:sts::111122223333:assumed-role/ReportsReader/batch-2026-08-21" } ``` Three fields, and they are the resolution of whatever credentials signed the request — the environment variables, the profile, the credential the SDK fetched. This matters more than it sounds, because a large share of "IAM is broken" incidents are really "I am not the principal I assumed I was": a stale `AWS_PROFILE`, an `AWS_ACCESS_KEY_ID` still exported in the shell (environment credentials outrank a profile in the SDK's lookup order), or a job running in the wrong account entirely. One command settles it before you start editing policies. ## Reading the ARN For a long-term IAM user credential: ``` arn:aws:iam::111122223333:user/dana ``` For an assumed role session: ``` arn:aws:sts::111122223333:assumed-role/ReportsReader/batch-2026-08-21 ``` Note the service is `sts`, not `iam`. The two path segments after `assumed-role/` are the **role name** and the **role session name** — the string the caller passed as `RoleSessionName` when it assumed. One more subtlety: if the role was created under an IAM path (say `/service/ReportsReader`), the assumed-role ARN does not include that path, only the role's name. That is a routine surprise when someone tries to match sessions with a wildcard pattern. The `UserId` field has a matching two-part shape: the role's unique ID (the `AROA…` value) then a colon then the session name. That composite string is exactly what the `aws:userid` condition key returns for a role session, which is how you write a policy that admits only one specific session name. ## The ARN you use in policies is a different one This is the trap. The STS `assumed-role` ARN identifies a *session*; it is not something you put in a `Principal` element. To let this role's sessions read a bucket in another account, the bucket policy names the IAM role: ```json "Principal": { "AWS": "arn:aws:iam::111122223333:role/ReportsReader" } ``` Pasting the `arn:aws:sts::…:assumed-role/…` form there does not work as intended, and people burn a lot of time on it because the string they copied is right there in the error message. Rule: **`sts` ARNs describe who is calling right now; `iam` ARNs are what you reference in policies.** ## Why it needs no permissions `sts:GetCallerIdentity` is deliberately unrestricted. AWS documents that no permissions are required and that the call still succeeds even if a policy explicitly denies the action — the reasoning is that a denial message would reveal the same identity information the call returns, so denying it buys nothing. Practically, this makes it a reliable probe in a locked-down environment: if it fails, your credentials are wrong or expired, not under-permissioned. An `ExpiredToken` error here means exactly what it says. ## Session names are your audit handle Because a role is a shared identity, the session name is the only thing distinguishing one user of it from another. Every CloudTrail event carries it, so a role session named `alice` and one named `terraform-apply-4821` are trivially separable in an investigation, while ten sessions all named `session1` are not. Treat the session name as a required field with a convention — the human's identifier, the pipeline run ID, the job name — rather than a throwaway string. Some organizations enforce this from the trust policy with a condition on `sts:RoleSessionName`. ## The practical debugging loop When a call is denied: run `get-caller-identity` first and confirm the account and the role are what you expect; read the failing action out of the error message; then decide whether you are looking at a trust problem or a permissions problem. Skipping the first step is how engineers end up carefully fixing a policy in the right account for a session that was actually running in the wrong one.
- Why can't you paste the assumed-role ARN you got back into a bucket policy's Principal element?That ARN identifies a live session, not a durable identity, and the `Principal` element expects the IAM role ARN — `arn:aws:iam::111122223333:role/ReportsReader`. Naming the role covers every session it produces. If you genuinely need to single out one session, do it with a `Condition` on `aws:userid`, not by naming the session in `Principal`.
- What does the UserId field look like for a role session, and where is that value useful?It is the role's unique ID and the session name joined by a colon, such as `AROAEXAMPLEID:batch-2026-08-21`. That exact string is what the `aws:userid` condition key resolves to, so it is how you write a policy that admits only one named session — useful when a shared role must be narrowed for a specific automated caller.
- get-caller-identity works but every other call is denied. What has that told you?That your credentials are valid and unexpired, and the identity is resolved — so the problem is authorization, not authentication. Confirm the account and role in the ARN are the ones you meant, then look at the role's permissions policies and any resource policy on the target. It rules out the whole class of stale-credential causes in one step.
saying these in an interview costs you the question
- Using the sts assumed-role ARN as a Principal in a policy
- Thinking the command needs an IAM allow to work
- Treating the session name as a meaningless throwaway string
- Expecting the assumed-role ARN to include the role's IAM path