Credentials, Profiles & AssumeRole
AWS credentials flow through multiple providers - discover how to load them from the environment, config files, STS, or instance metadata, and assume roles for cross-account or temporary access.
Search across all documentation pages
AWS credentials flow through multiple providers - discover how to load them from the environment, config files, STS, or instance metadata, and assume roles for cross-account or temporary access.
Boto3 and SDK v3 both walk a chain: environment variables, then config files, then container/instance metadata, so you rarely need to specify credentials explicitly.
# --- Python (boto3) ---
import boto3
# Uses default provider chain automatically
session = boto3.Session()
s3 = session.client("s3")
response = s3.list_buckets()// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
const s3 = new S3Client({ credentials: fromNodeProviderChain() });
const response = await s3.send(new ListBucketsCommand({}));For testing or CI/CD without profiles, pass access key and secret directly - but never hardcode in source code.
# --- Python (boto3) ---
import boto3
s3 = boto3.client(
"s3",
aws_access_key_id="AKIAIOSFODNN7EXAMPLE",
aws_secret_access_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
)
response = s3.list_buckets()// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({
credentials: {
accessKeyId: "AKIAIOSFODNN7EXAMPLE",
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
});
const response = await s3.send(new ListBucketsCommand({}));Load a profile from ~/.aws/config or ~/.aws/credentials to switch between dev, staging, and production IAM users.
# --- Python (boto3) ---
import boto3
# Uses [production] section in ~/.aws/config
session = boto3.Session(profile_name="production")
ec2 = session.client("ec2")
response = ec2.describe_instances()// --- TypeScript (AWS SDK v3) ---
import { EC2Client, DescribeInstancesCommand } from "@aws-sdk/client-ec2";
import { fromIni } from "@aws-sdk/credential-providers";
const ec2 = new EC2Client({ credentials: fromIni({ profile: "production" }) });
const response = await ec2.send(new DescribeInstancesCommand({}));Exchange your identity for short-lived credentials for another role or AWS account.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
creds = sts.assume_role(
RoleArn="arn:aws:iam::111122223333:role/CrossAccountRole",
RoleSessionName="my-app-session"
)["Credentials"]
print(creds["Expiration"]) # 2026-07-23 18:30:00+00:00// --- TypeScript (AWS SDK v3) ---
import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({});
const { Credentials } = await sts.send(new AssumeRoleCommand({
RoleArn: "arn:aws:iam::111122223333:role/CrossAccountRole",
RoleSessionName: "my-app-session"
}));
console.log(Credentials.Expiration);Add an ExternalId when assuming a role shared with a third party - it acts as a secret handshake.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
creds = sts.assume_role(
RoleArn="arn:aws:iam::999999999999:role/ThirdPartyRole",
RoleSessionName="vendor-session",
ExternalId="unique-external-id-12345"
)["Credentials"]// --- TypeScript (AWS SDK v3) ---
import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({});
const { Credentials } = await sts.send(new AssumeRoleCommand({
RoleArn: "arn:aws:iam::999999999999:role/ThirdPartyRole",
RoleSessionName: "vendor-session",
ExternalId: "unique-external-id-12345"
}));Let the SDK handle credential refresh - get short-lived credentials from AssumeRole without manually re-calling it.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
# boto3 auto-refreshes via assume_role credentials
assumed_session = boto3.Session(
profile_name="assume-role-profile" # configured with role_arn
)
s3 = assumed_session.client("s3")
response = s3.list_buckets() # auto-refreshed if expired// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
import { fromTemporaryCredentials } from "@aws-sdk/credential-providers";
const s3 = new S3Client({
credentials: fromTemporaryCredentials({
params: { RoleArn: "arn:aws:iam::111122223333:role/App", RoleSessionName: "app" }
})
});
const response = await s3.send(new ListBucketsCommand({}));Assume a role using an OpenID Connect token from Kubernetes (IRSA) or another identity provider.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
with open("/var/run/secrets/eks.amazonaws.com/serviceaccount/token") as f:
token = f.read()
creds = sts.assume_role_with_web_identity(
RoleArn="arn:aws:iam::111122223333:role/EKSRole",
RoleSessionName="eks-pod",
WebIdentityToken=token
)["Credentials"]// --- TypeScript (AWS SDK v3) ---
import { STSClient, AssumeRoleWithWebIdentityCommand } from "@aws-sdk/client-sts";
import { fromWebToken } from "@aws-sdk/credential-providers";
import { readFileSync } from "fs";
const sts = new STSClient({});
// Or use fromWebToken for automatic handling
const token = readFileSync("/var/run/secrets/eks.amazonaws.com/serviceaccount/token", "utf8");
const { Credentials } = await sts.send(new AssumeRoleWithWebIdentityCommand({
RoleArn: "arn:aws:iam::111122223333:role/EKSRole",
RoleSessionName: "eks-pod",
WebIdentityToken: token
}));Use AWS SSO to authenticate - boto3 and SDK v3 automatically read the .aws/sso/cache directory.
# --- Python (boto3) ---
import boto3
# ~/.aws/config has [profile myprofile] with sso_* settings
session = boto3.Session(profile_name="myprofile")
iam = session.client("iam")
response = iam.list_users()// --- TypeScript (AWS SDK v3) ---
import { IAMClient, ListUsersCommand } from "@aws-sdk/client-iam";
import { fromSSO } from "@aws-sdk/credential-providers";
const iam = new IAMClient({ credentials: fromSSO({ profile: "myprofile" }) });
const response = await iam.send(new ListUsersCommand({}));On ECS Fargate or ECS EC2, the SDK reads credentials from the container credential provider via an environment variable endpoint.
# --- Python (boto3) ---
import boto3
# AWS_CONTAINER_CREDENTIALS_FULL_URI is set by ECS/Fargate
session = boto3.Session()
s3 = session.client("s3")
response = s3.list_buckets()// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
import { fromContainerMetadata } from "@aws-sdk/credential-providers";
const s3 = new S3Client({ credentials: fromContainerMetadata() });
const response = await s3.send(new ListBucketsCommand({}));On EC2, query the instance metadata service for temporary credentials attached to the instance profile.
# --- Python (boto3) ---
import boto3
# boto3 reads EC2 instance metadata automatically
session = boto3.Session()
ec2 = session.client("ec2")
response = ec2.describe_instances()// --- TypeScript (AWS SDK v3) ---
import { EC2Client, DescribeInstancesCommand } from "@aws-sdk/client-ec2";
import { fromInstanceMetadata } from "@aws-sdk/credential-providers";
const ec2 = new EC2Client({ credentials: fromInstanceMetadata() });
const response = await ec2.send(new DescribeInstancesCommand({}));Call GetCallerIdentity to see the current AWS account ID, user ARN, and assumed-role details.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
identity = sts.get_caller_identity()
print(identity["Account"]) # 123456789012
print(identity["Arn"]) # arn:aws:iam::123456789012:user/alice// --- TypeScript (AWS SDK v3) ---
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({});
const identity = await sts.send(new GetCallerIdentityCommand({}));
console.log(identity.Account); // 123456789012
console.log(identity.Arn); // arn:aws:iam::123456789012:user/aliceGenerate multi-factor authentication (MFA) session credentials when MFA is required by your role policy.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
creds = sts.get_session_token(
SerialNumber="arn:aws:iam::123456789012:mfa/alice",
TokenCode="123456", # 6-digit code from MFA device
DurationSeconds=3600
)["Credentials"]
print(creds["SessionToken"])// --- TypeScript (AWS SDK v3) ---
import { STSClient, GetSessionTokenCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({});
const { Credentials } = await sts.send(new GetSessionTokenCommand({
SerialNumber: "arn:aws:iam::123456789012:mfa/alice",
TokenCode: "123456",
DurationSeconds: 3600
}));
console.log(Credentials.SessionToken);Explicitly pull AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from the environment - useful for testing or CI/CD pipelines.
# --- Python (boto3) ---
import os
import boto3
# boto3 reads AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY automatically
access_key = os.environ.get("AWS_ACCESS_KEY_ID")
secret_key = os.environ.get("AWS_SECRET_ACCESS_KEY")
s3 = boto3.client("s3")
response = s3.list_buckets()// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
import { fromEnv } from "@aws-sdk/credential-providers";
const s3 = new S3Client({ credentials: fromEnv() });
const response = await s3.send(new ListBucketsCommand({}));Compose multiple credential providers so the SDK tries your custom source first, then falls back to the default chain.
# --- Python (boto3) ---
import boto3
from botocore.credentials import Credentials
# Create session with custom credential provider
session = boto3.Session()
# Manually set credentials if available, else fall back to default
s3 = session.client("s3")
response = s3.list_buckets()// --- TypeScript (AWS SDK v3) ---
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
import { chain, fromEnv, fromNodeProviderChain } from "@aws-sdk/credential-providers";
const s3 = new S3Client({
credentials: chain(
fromEnv(), // try env vars first
fromNodeProviderChain() // then default chain
)
});
const response = await s3.send(new ListBucketsCommand({}));Extract the Expiration timestamp from temporary credentials returned by AssumeRole or GetSessionToken.
# --- Python (boto3) ---
import boto3
sts = boto3.client("sts")
creds = sts.assume_role(
RoleArn="arn:aws:iam::111122223333:role/App",
RoleSessionName="session-1"
)["Credentials"]
expiry = creds["Expiration"] # datetime object
print(f"Expires at: {expiry}")// --- TypeScript (AWS SDK v3) ---
import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({});
const { Credentials } = await sts.send(new AssumeRoleCommand({
RoleArn: "arn:aws:iam::111122223333:role/App",
RoleSessionName: "session-1"
}));
console.log(`Expires at: ${Credentials.Expiration}`);Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Reviewed by Chris St. John·Last updated Jul 23, 2026