Chapter 12 of 16 · Application/workload user · orders-api

AWS IAM Authentication

Authenticate an AWS workload by proving IAM identity through a signed request instead of distributing a Vault login secret.

Chapter contract

Persona: Application/workload user · orders-apiPhase: AWS and EKS workloadsEstimated time: 40 minutes

Prerequisites:

AWS CLI and a named learning profile for identity inspection; the lab itself stays offline.

User-visible outcome:

An AWS workload-auth role is bound to the intended account and exact IAM principal without static keys.

Learning objectives

Consumer flow

AWS provider chainstep 1Signed STS requeststep 2Vault AWS rolestep 3Scoped Vault tokenstep 4

Ownership boundary

OwnerConsumer-facing responsibility
You ownDefines consumption, validation, reload, and stop-using behavior.
Platform team ownsProvides trusted runtime identity, protected delivery, network, and telemetry.
Vault ownsOperates auth mounts, policies, engines, audit, and recovery.

Core concepts

iam auth

Vault validates a signed GetCallerIdentity request.

ec2 auth

Vault validates instance identity with different trade-offs.

Provider chain

The SDK's ordered sources for temporary credentials.

Bound principal

The AWS identity or attributes a Vault role accepts.

Commands and configuration

aws sso login --profile vault-learning
aws sts get-caller-identity \
  --profile vault-learning \
  --query '{Account:Account,Arn:Arn}' --output json
aws configure get region --profile vault-learning

AWS_PROFILE=vault-learning AWS_REGION=us-east-2 \
  vault login -method=aws -no-print role=lockbox-orders-api
vault token lookup -format=json \
  | jq '{policies:.data.policies,ttl:.data.ttl}'

The AWS auth client signs the request through the standard provider chain. The signed URL, headers, and body never need to be copied into shell variables or logs. Use the region approved for the platform-supplied Vault role.

Secret-safety stop

Stop: Signed request fields are authentication material during their validity window. Keep them out of logs, traces, tickets, and history.

Failure drill

SymptomVault rejects AWS login or maps the wrong role.
Likely causesWrong provider identity, role binding, STS endpoint, clock, X-Vault-AWS-IAM-Server-ID header mismatch, or server-side AWS permission.
Inspect safelyRun get-caller-identity; record account, ARN, role, region, server ID configuration, and time.
Do not printAccess keys, session token, signed fields, metadata response, or Vault token.

Break it / fix it

Break it: Use a wildcard IAM principal in the role worksheet.

Show diagnosis and fix

Fix it: Bind the intended account and exact application role after get-caller-identity verification.

Escalate with time, endpoint, auth path, role, mount, namespace when relevant, status code, request ID, and sanitized error class. Never attach a credential or response body.

Try it

Bootstrap boundary

Platform-supplied external configuration is represented by reserved example inputs; this lab applies nothing.

Cost:

$0; offline validation with no external resource changes

Starting state:

Use the tracked example and offline validator; real GitLab, AWS, and Kubernetes configuration remains platform-owned.

User actions:

Complete the offline role worksheet with redacted identity metadata and validate the role contract; no AWS or Vault changes occur.

cd learn-vault/labs/aws-iam
cp role-input.example.json ../../.runtime/aws-role-input.json
python3 validate_role_input.py ../../.runtime/aws-role-input.json
rm -f ../../.runtime/aws-role-input.json

Success criteria:

Complete every item in the Verify section using metadata-only evidence; no secret value appears in terminal output or tracked files.

Troubleshooting:

Use the Failure drill and Break it / fix it evidence fields. Stop before broadening policy, weakening identity or TLS checks, or copying secret-bearing diagnostics.

Verify

  1. The input names account, exact principal pattern, auth type, policy, and finite TTL.
  2. No static AWS key appears.
  3. The validator rejects a wildcard-only principal.
Evidence rule: retain only status, policy names, TTLs, versions, timestamps, fingerprints, and error classes. Never retain secret values.

Cleanup

Remove the runtime worksheet. This offline lab creates no external resources.

Project Lockbox increment

EC2 orders-api uses its instance role; the Vault role is bound to the intended account and app role.

Quick check

Does Vault need the AWS secret key?

No. The client sends a signed request for validation.

Why get-caller-identity first?

It proves the selected provider identity.

Why reject wildcard binding?

It would defeat workload isolation.

When prefer Kubernetes auth?

When pod service-account identity is the intended trust model.

Gotchas

Recap and next

AWS auth removes a distributed Vault secret; the narrow role binding remains the real security boundary.

Primary references

Continue →