Skip to content
HackIndex logo

HackIndex

AWS Credential Types & Resolution Chain

4 min read May 24, 2026

AWS uses several credential formats. Knowing the type tells you the source, lifetime, and what operations it supports.

Long-term Access Keys

AKIA...

Issued to IAM users. No expiry unless manually rotated or deleted. Permissions come from IAM policies attached to that user.

Finding AKIA keys in source code, S3 objects, or environment variables is high-value — they persist indefinitely until rotated.

Temporary Session Credentials

ASIA...

Three-part credential set: access key ID, secret access key, and session token. Always used together. Generated by STS — for assumed roles, federated identities, EC2 instance profiles, and Lambda execution roles.

Expiry ranges from 15 minutes to 12 hours depending on how they were issued. The session token must accompany every API call.

Export as environment variables:

┌──(kali㉿kali)-[~]
└─$ export AWS_ACCESS_KEY_ID=ASIA...
┌──(kali㉿kali)-[~]
└─$ export AWS_SECRET_ACCESS_KEY=...
┌──(kali㉿kali)-[~]
└─$ export AWS_SESSION_TOKEN=...

Or store in ~/.aws/credentials:

[profile-name]
aws_access_key_id = ASIA...
aws_secret_access_key = ...
aws_session_token = ...

Role Credentials

Obtained via sts:AssumeRole. Returns temporary credentials scoped to the assumed role's permission set:

┌──(kali㉿kali)-[~]
└─$ aws sts assume-role --role-arn arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME --role-session-name $SESSION_NAME --profile $PROFILE
Explain command
--role-arn Full ARN of the IAM role to assume.
--role-session-name $SESSION_NAME Identifier for this session, visible in CloudTrail logs.

Extract and export the returned values:

┌──(kali㉿kali)-[~]
└─$ export AWS_ACCESS_KEY_ID=$(aws sts assume-role --role-arn arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME --role-session-name $SESSION_NAME --query Credentials.AccessKeyId --output text)
┌──(kali㉿kali)-[~]
└─$ export AWS_SECRET_ACCESS_KEY=$(aws sts assume-role --role-arn arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME --role-session-name $SESSION_NAME --query Credentials.SecretAccessKey --output text)
┌──(kali㉿kali)-[~]
└─$ export AWS_SESSION_TOKEN=$(aws sts assume-role --role-arn arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME --role-session-name $SESSION_NAME --query Credentials.SessionToken --output text)

Role credentials can be chained — assume role A, then from A assume role B. Useful for cross-account lateral movement where no direct trust exists between your current identity and the target role.

Web Identity Tokens

Used by EKS service accounts, GitHub Actions, and other OIDC-federated workloads. The workload exchanges a signed JWT for temporary STS credentials:

┌──(kali㉿kali)-[~]
└─$ aws sts assume-role-with-web-identity --role-arn arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME --role-session-name $SESSION_NAME --web-identity-token file://$TOKEN_FILE
Explain command
--web-identity-token file://$TOKEN_FILE Path to JWT token file. In EKS mounted at /var/run/secrets/eks.amazonaws.com/serviceaccount/token.

In EKS, the token is mounted at /var/run/secrets/eks.amazonaws.com/serviceaccount/token. If a pod's service account is bound to an overpermissioned IAM role, this token is the escalation path.

Credential Resolution Chain

AWS SDKs and CLI resolve credentials in this order — first match wins:

  1. Explicit parameters in code or CLI flags

  2. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)

  3. AWS CLI credentials file (~/.aws/credentials)

  4. AWS CLI config file (~/.aws/config)

  5. Container credential provider (ECS task role via internal metadata endpoint)

  6. EC2 instance profile (IMDS at 169.254.169.254)

During post-exploitation on EC2 or ECS, instance profile credentials are picked up automatically by any tool using the SDK — the chain reaches step 5 or 6 without manually extracting and exporting keys.

Identifying Credential Type and Source

Always run this immediately after obtaining credentials:

┌──(kali㉿kali)-[~]
└─$ aws sts get-caller-identity --profile $PROFILE
{
    "UserId": "AIDA...",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/jdoe"
}

The Arn field reveals the principal type:

  • arn:aws:iam::...:user/name — IAM user, long-term keys

  • arn:aws:sts::...:assumed-role/RoleName/Session — assumed role

  • arn:aws:sts::...:assumed-role/ec2-role/i-abc123 — EC2 instance profile

  • arn:aws:sts::...:assumed-role/RoleName/GitHubActions — OIDC federation

The account ID in the ARN identifies the target account. A different account ID between your source credentials and the assumed role indicates a cross-account move.