An AWS IAM role is an identity that AWS services or users can assume to get temporary credentials - no long-lived access keys. Roles are how EC2 instances, Lambda functions, ECS tasks, and EKS pods get AWS permissions. The team that uses IAM Roles Anywhere (covered in AWS docs) extends the same model to on-prem workloads. The team that runs K8s uses IRSA (IAM Roles for Service Accounts) for pod-level AWS access.
Table of contents
- What a role actually is
- Roles vs users vs groups
- Common service roles
- IRSA (IAM Roles for Service Accounts)
- The trust policy
- Common pitfalls
- FAQ
What a role actually is
A role has three parts: a trust policy (who can assume), a permission policy (what they can do), and a session duration (how long credentials last). When something assumes the role, STS issues temporary credentials that auto-expire (15min-12hr default). No long-lived secret to leak.
The IAM User Guide describes the model. The key insight: roles have no username/password of their own. They’re only useful when something (a service, a user via federation, another role) assumes them.
Roles vs users vs groups
Users: long-lived identities for humans. Groups: collections of users with shared permissions. Roles: identities that AWS services or federated users can assume.
The team that uses roles for service-to-service auth avoids the #1 AWS security mistake: long-lived access keys in code or env vars. The team that uses roles for human auth uses SSO (federated users assume roles via SAML/OIDC).
Common service roles
- EC2 instance role: attaches to EC2 via instance profile. SDK on the instance calls
metadata serviceto get temp credentials. - Lambda execution role: assigned at function creation. Lambda’s runtime fetches credentials automatically.
- ECS task role: per-task. ECS agent injects credentials into the task’s container env.
- EKS pod role (IRSA): per-ServiceAccount. K8s service account is annotated with the role ARN; pod gets AWS_WEB_IDENTITY_TOKEN_FILE and STS exchanges it.
The team that uses service-specific roles (Lambda role for Lambda, task role for ECS) follows least-privilege. The team that uses one ‘admin’ role for everything has a security incident waiting to happen.
IRSA (IAM Roles for Service Accounts)
IRSA lets a K8s pod assume an IAM role tied to a ServiceAccount. The flow:
- Create IAM role with trust policy for the K8s OIDC provider.
- Annotate the ServiceAccount:
eks.amazonaws.com/role-arn: arn:aws:iam::...:role/myrole. - Pod that uses the ServiceAccount gets
AWS_WEB_IDENTITY_TOKEN_FILEenv var. - AWS SDK reads the token, exchanges via STS for AWS credentials.
The team that uses IRSA has per-pod AWS access without static credentials. The team that uses instance roles for K8s nodes has cluster-wide AWS access - too broad for production.
The trust policy
The trust policy says who can assume the role. For service roles:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
For cross-account access:
{
"Principal": {"AWS": "arn:aws:iam::123456789012:root"}
}
The team that gets the trust policy right has working role assumption. The team that confuses trust policy (who can assume) with permission policy (what they can do) has silent failures.
Common pitfalls
- Forgetting
sts:AssumeRolein the trust policy - role can be created but never assumed. - Permission boundary tighter than the role’s policy - effective permissions are the intersection.
- Cross-account roles without a trust policy entry for the source account.
- Long session durations (12hr) - shorter is safer; long-lived sessions amplify blast radius if leaked.
- Using one ‘admin’ role for production and dev - least-privilege is the discipline.
The team that treats IAM roles as production code (version-controlled, reviewed) has fewer surprises than the team that creates them in the console ad-hoc.
FAQ
How long do IAM role credentials last?
Default: 1 hour. Configurable from 15 minutes to 12 hours. The team that uses shorter durations has less blast radius if credentials leak. The team that uses 12 hours has fewer STS calls but more risk.
Can a role assume another role?
Yes - role chaining. The trust policy of the target role must allow the source role’s ARN. The chain maxes out at 1 hour (hard limit by STS), even if the target role has longer max session duration.
What’s the difference between a role and a policy?
A role is an identity with trust + permission policies. A policy is a JSON document of permissions that can be attached to a role, user, or group. The team that uses managed policies (AWS-managed) has the right starting point; custom policies are for the team’s specific needs.
Should I use IAM Roles Anywhere for on-prem?
Yes - if you have on-prem workloads that need AWS API access. Roles Anywhere issues short-lived X.509 certs that map to IAM roles. The team that uses long-lived access keys for on-prem has a credential rotation problem.
How do I rotate a role’s trust policy?
Update the trust policy JSON, save, and changes are immediate (no propagation delay). The team that needs audit trail uses aws iam update-assume-role-policy with version tracking.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: