AWS Identity and Access Management (IAM) is the foundational service for controlling who and what can access AWS resources. It manages users, groups, roles, and policies — and acts as the policy decision point for nearly every AWS API call. Modern AWS deployments treat IAM as the primary security boundary: principals are denied by default and granted access only through explicit, least-privilege policies.
sts:AssumeRole, returning short-lived credentials (15 min to 12 hours) used by EC2, Lambda, ECS tasks, and federated humans.aws:MultiFactorAuthPresent in policy conditions.
import boto3
sts = boto3.client("sts")
resp = sts.assume_role(
RoleArn="arn:aws:iam::222233334444:role/DataReader",
RoleSessionName="analytics-job-2026-04-25",
DurationSeconds=3600,
)
creds = resp["Credentials"]
# Use the temporary credentials in a new session
prod = boto3.Session(
aws_access_key_id=creds["AccessKeyId"],
aws_secret_access_key=creds["SecretAccessKey"],
aws_session_token=creds["SessionToken"],
region_name="us-west-2",
)
s3 = prod.client("s3")
for obj in s3.list_objects_v2(Bucket="prod-data-lake")["Contents"]:
print(obj["Key"])
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOneBucketPrefix",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::prod-data-lake",
"arn:aws:s3:::prod-data-lake/reports/*"
],
"Condition": {
"Bool": {"aws:MultiFactorAuthPresent": "true"},
"IpAddress": {"aws:SourceIp": ["203.0.113.0/24"]}
}
}
]
}
A user is a long-lived identity with static credentials (password, access keys) tied to a specific person or service. A role is an identity assumed temporarily — anyone or anything that satisfies the trust policy can assume it and receive short-lived STS credentials. Modern best practice is to minimize users and prefer roles assumed through SSO or OIDC federation.
Both are evaluated together. An explicit Deny in either always wins. Otherwise, an Allow in either is sufficient for same-account access. For cross-account access, both the principal's identity policy and the resource policy must allow the action.
A managed policy that defines the maximum permissions an identity-based policy can grant. The effective permissions are the intersection of the identity policy and the boundary. Used to safely delegate IAM administration — a junior admin can create roles, but only within the ceiling the boundary defines.
Create an IAM role with the required S3 policy, attach it via an instance profile, and the EC2 metadata service (IMDSv2) will deliver rotating temporary credentials to the AWS SDK automatically.
OIDC lets external identity providers (GitHub Actions, GitLab, CircleCI) issue short-lived JWTs that AWS exchanges for STS credentials via sts:AssumeRoleWithWebIdentity. This eliminates long-lived AWS access keys stored as CI secrets — the most common source of AWS credential leaks.
SCPs (Service Control Policies) are AWS Organizations guardrails that cap what any principal in a member account can do — they grant nothing on their own. IAM policies grant or deny specific permissions to specific identities. SCPs filter the menu; IAM policies make the order.
IAM is the keystone of AWS security. Treat every credential as ephemeral, prefer roles and federation over users, layer SCPs and permissions boundaries above identity policies, and continuously narrow permissions with Access Analyzer. Done right, IAM is invisible; done wrong, it is the breach.