How does AWS STS AssumeRole actually issue temporary credentials, and why is that safer than long-lived access keys for service-to-service access?
Quick Answer
AssumeRole is an STS, Security Token Service, API call where a caller, a user or more commonly an AWS service like an EC2 instance or Lambda function, presents an identity and requests to become a specific IAM role, and STS returns a short-lived access key, secret key, and session token, typically valid from 15 minutes to a few hours, instead of any permanent credential. This is safer than long-lived access keys because a leaked temporary credential expires quickly on its own and is scoped to exactly the permissions of the assumed role, whereas a leaked long-lived access key remains valid indefinitely until someone notices and manually revokes it.
Detailed Answer
Imagine a hotel that, instead of giving long-term employees a single master key that opens every room forever, issues a fresh keycard every shift that only opens the specific rooms that employee needs for that shift and automatically deactivates itself at the end of the shift. If a keycard is lost or stolen, the exposure window is just the remainder of that one shift — nobody has to track down and physically disable a master key that could open every door indefinitely, for years, until someone happens to notice it's missing.
AWS IAM's AssumeRole mechanism, backed by the Security Token Service, was designed to replace exactly the older pattern of generating a long-lived access key and secret key pair, essentially a master key that works until someone manually deletes it, with this shift-based, auto-expiring keycard model. This matters because long-lived access keys are a huge source of real breaches — they get accidentally committed to git repositories, baked into container images, or leaked in logs, and unlike a temporary credential, they don't self-destruct, so a leak from months ago can still be actively exploitable if nobody caught it in the meantime.
Internally, when a service like checkout-worker running on an EC2 instance or in a Lambda function needs to access, say, an S3 bucket or a DynamoDB table, it calls sts:AssumeRole, often transparently via the AWS SDK's default credential provider chain, which for EC2 fetches credentials from the instance metadata service, or for Lambda from environment variables injected by the Lambda execution environment, specifying the target role's ARN. STS validates that the calling identity is permitted to assume that role, checked against the role's trust policy, which explicitly lists who's allowed to assume it, and if allowed, returns a temporary AccessKeyId, SecretAccessKey, and SessionToken bundle valid for a configured duration, default one hour, configurable up to the role's max session duration. All subsequent AWS API calls include that session token alongside the temporary keys, and AWS automatically rejects any request using expired temporary credentials outright.
In production, this pattern is what underlies EC2 instance profiles, Lambda execution roles, and cross-account access. A payments-api service can be granted an instance profile role scoped tightly to exactly the S3 bucket and DynamoDB table it needs, and nothing more, with credentials that rotate automatically every hour without any human or deployment process ever touching a static secret. Teams monitor CloudTrail for AssumeRole events to track exactly which identities are assuming which roles and from where, which is also a strong security signal — an AssumeRole call from an unexpected IP range or an unusual role and service combination is a classic indicator of compromised infrastructure worth investigating immediately.
The gotcha: teams sometimes still create long-lived IAM user access keys just to get something working quickly, like a local script or a CI job, and because those keys never expire on their own, they tend to persist for years, attached to overly broad permissions granted temporarily that nobody ever tightens, turning what was meant to be a quick shortcut into a long-term, high-blast-radius credential far more dangerous than the fleet of properly-scoped, auto-expiring role-based credentials everything else uses. Auditing for and eliminating long-lived access keys entirely, replacing them with role assumption, including for CI/CD via OIDC federation, is a common senior-level security initiative.