Lesson 033 · AWS Learning Path

AWS 033: Prove caller identity, Region, and account without creating resources

· Published · 5 min read

Human, workload, and federated identities pass authentication before authorization grants cloud access

The problem

The most dangerous automation mistake is acting in the wrong account or Region with the wrong identity. A command can be valid and still modify the wrong environment.

Every later mutating lab begins with an identity-and-scope preflight.

Final outcome

You will build and run a read-only preflight that proves AWS principal, account, Region, profile source, and visible Availability Zones. You will compare the result with the Console and create a redacted baseline.

Required safety state

  • Root is not used.
  • AWS CLI v2 is installed or CloudShell is open.
  • A temporary-authentication course profile exists for local CLI.
  • The fixed course Region is recorded.
  • No command in this lab creates, updates, or deletes a resource.

Evidence model

Who: principal ARN and session type
Where: AWS account and partition
Region: resolved default and explicit target
Interface: CloudShell or local profile
Permission: successful read-only operations
Time: evidence timestamp

GetCallerIdentity returns the identity used to sign a request. AWS documents that no permission is required for the operation itself. Even an explicit deny can still yield the same identity information in the error response. It proves caller context, not authorization to other services.

Console preflight

  1. Sign in with the daily identity.
  2. Open the account menu and record the identity type.
  3. Select the fixed course Region.
  4. Open EC2 and record the Region shown.
  5. Open Availability Zones and record names and IDs.
  6. Open Instances and confirm this is inspection only.

Keep the page open.

CLI preflight

For local CLI:

COURSE_PROFILE="course"
COURSE_REGION="ap-south-1"

aws configure list --profile "$COURSE_PROFILE"

aws sts get-caller-identity \
  --profile "$COURSE_PROFILE" \
  --output json \
  --no-cli-pager

aws ec2 describe-availability-zones \
  --profile "$COURSE_PROFILE" \
  --region "$COURSE_REGION" \
  --filters Name=zone-type,Values=availability-zone \
  --query 'AvailabilityZones[].{Name:ZoneName,Id:ZoneId,State:State}' \
  --output table \
  --no-cli-pager

For CloudShell, remove the --profile options after proving its current caller identity.

Inspect the exit status immediately after each important command:

printf 'exit=%s\n' "$?"

Do not run the printf only once at the end and assume it represents every earlier command.

Add account Region status

If the daily identity has Account Management read permission:

aws account get-region-opt-status \
  --profile "$COURSE_PROFILE" \
  --region-name "$COURSE_REGION" \
  --output json \
  --no-cli-pager

If it is denied, record the exact action and continue. An access denial is valid evidence of the permission boundary. Do not switch to root just to make a read-only optional step green.

Private preflight script

Create aws-preflight.sh locally:

#!/usr/bin/env bash
set -u

course_profile="${1:-course}"
course_region="${2:-ap-south-1}"

printf 'time_utc=%s\n' "$(date -u +%FT%TZ)"
printf 'profile=%s\n' "$course_profile"
printf 'region=%s\n' "$course_region"

aws configure list --profile "$course_profile"
aws sts get-caller-identity \
  --profile "$course_profile" \
  --output json \
  --no-cli-pager
aws ec2 describe-availability-zones \
  --profile "$course_profile" \
  --region "$course_region" \
  --query 'AvailabilityZones[].{Name:ZoneName,Id:ZoneId,State:State}' \
  --output table \
  --no-cli-pager

Read it line by line before running:

bash -n aws-preflight.sh
bash aws-preflight.sh course ap-south-1

bash -n checks shell syntax but does not execute AWS calls. The script is intentionally private because raw output contains account and principal identifiers.

Redact correctly

Create preflight-evidence.md manually:

Time UTC:
Interface:
Profile:
Credential source type:
Principal type:
Account: verified and redacted
Course Region:
Region status:
Availability Zone names and IDs:
Console match:
Read permission failures:
Ready for mutation: yes or no

Do not replace identifiers with realistic-looking numbers. Use <account-redacted> and <principal-redacted>.

Redaction should preserve useful type information. For example, record assumed-role rather than copying a complete role-session ARN.

Mutation gate

Before any future create, update, or delete action, the learner must be able to answer:

  1. Is this the intended AWS account?
  2. Is this a non-root approved principal?
  3. Is this the intended Region?
  4. Is the target service regional or global?
  5. What resources should already exist?
  6. What will the command change?
  7. What can charge money?
  8. What is the verification?
  9. What is the cleanup and rollback?

A script that cannot prove these should stop before mutation.

Expected results

Success:

  • get-caller-identity exits 0;
  • principal is not root;
  • account matches the private P02 record;
  • explicit Region matches Console;
  • Availability Zone list matches in both interfaces;
  • credential source is temporary or approved;
  • evidence is redacted.

Failure examples:

  • wrong account;
  • root ARN;
  • unexpected environment credential;
  • ExpiredToken;
  • comparison shows another Region;
  • optional account status is denied.

Wrong account, root, or unknown credential source is a stop condition. An optional denied read can be documented and remediated through least privilege.

Troubleshooting

SymptomCheckSafe correction
wrong principalprofile and environment precedencelogout, unset override, use approved profile
wrong accountselected login/rolestop and authenticate correctly
wrong Regionprofile, environment, command optionset explicit course Region
expired tokensession durationrepeat approved login
zones differRegion or filteralign exact scope
script continues after failureshell error handling absentadd explicit status checks in later automation

Completion gate

Pass when Console and CLI agree on non-root identity type, private account record, Region, and Availability Zones; the script passes syntax check; stop conditions are documented; and shared evidence contains no full account or principal identifier.

No resources were created, modified, or deleted.

Official sources

Advertisement