DevOps Peach

AWS Basics · IAM – Identity and Access Management · Lesson 4 of 5

IAM Roles for Services

Grant temporary credentials to services and cross-account access with roles.

Practice interactively →

A role is assumed, not used as a permanent login

An IAM role has a permissions policy and a trust policy. The trust policy determines which principal may call sts:AssumeRole; the permissions policy determines what the session's temporary credentials can do.

flowchart LR
  E["EC2 instance<br/>app code"] --> IP["Instance profile<br/>wraps the role"]
  IP --> STS["AWS STS<br/>AssumeRole"]
  STS --> TC["Temporary credentials<br/>expire, auto-rotate"]
  TC --> S3["Amazon S3<br/>GetObject"]
  TR["Trust policy<br/>ec2.amazonaws.com"] -.-> STS
  %% step E: Code on the instance needs to read from S3 without stored keys.
  %% step IP: An instance profile attaches the role to the instance.
  %% step STS: STS checks the trust policy: is this principal allowed to assume the role?
  %% step TC: It returns short-lived credentials, which the SDK picks up from instance metadata and refreshes automatically.
  %% step S3: Requests are allowed only as far as the role's permissions policy says.
  %% step TR: The trust policy names who may assume the role, here the EC2 service.

Trust policy

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }]
}

The Principal can be a service (lambda.amazonaws.com), another account (arn:aws:iam::111122223333:root), a specific role, or a federated identity provider (SAML, OIDC such as GitHub Actions).

Where roles are used

Temporary credentials rotate automatically, so do not run aws configure to store access keys on an instance. A role session lasts from 15 minutes up to the role's maximum session duration (1 hour by default, up to 12 hours).

Roles versus users and groups

A role is not “added to a user” like a group. A user or service assumes the role to receive a time-limited session, and the session has only the role's permissions, not the caller's. An explicit Deny still overrides the role's Allows, and permissions boundaries or SCPs still apply.

A service-linked role is created and managed by an AWS service for its own needs (for example Auto Scaling); you can view it but its trust is fixed.

Command Purpose
aws iam create-role --role-name ec2-s3-read --assume-role-policy-document file://trust.json Create a role with a trust policy
aws iam attach-role-policy --role-name ec2-s3-read --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess Attach a permissions policy
aws ec2 associate-iam-instance-profile ... Attach a role to a running instance
aws sts assume-role --role-arn ... --role-session-name test Assume a role manually

Traps: storing access keys on EC2 instead of using a role; editing the permissions policy when the error is in the trust policy; expecting the session to keep the caller's own permissions.

Practice interactively →