Command Palette

Search for a command to run...

Hectal
PHASE 1Beginner ~14 min· topic 2 of 4

Topic 1.2

Roles & AssumeRole

In one line

A role is an identity with no permanent credentials — anything allowed to 'assume' it receives short-lived temporary credentials instead, which is how EC2 instances, Lambda functions, CI pipelines, and other accounts should authenticate.

0/4 · 0%

Think of it like this

A hotel key card. A permanent employee badge (an IAM user's access key) works until someone remembers to revoke it. A hotel key card (a ROLE's temporary credentials) is issued at check-in, works only for your room, and simply stops working at checkout — if you lose it, the damage window is hours, not years.

Key ideas

  1. 01

    A ROLE has permission policies just like a user, but NO password and NO long-lived access keys. Instead it has a TRUST POLICY that says WHO is allowed to assume it — an AWS service (ec2.amazonaws.com, lambda.amazonaws.com), a user or role in this or another account, or an external identity provider (GitHub Actions via OIDC, for example).

  2. 02

    When a trusted principal calls sts:AssumeRole, AWS STS (Topic 1.4) returns TEMPORARY credentials — an access key ID, secret key, and SESSION TOKEN — that expire, by default after one hour. The caller then acts with the role's permissions, not its own.

  3. 03

    For EC2, you attach a role through an INSTANCE PROFILE. The AWS SDK inside the instance automatically fetches and refreshes the role's credentials from the instance metadata service — your code never sees or stores a key. Lambda, ECS tasks, and EKS pods (via IRSA / Pod Identity) work the same way with their own mechanisms.

  4. 04

    The single most common AWS security failure is a long-lived access key committed to a repo, baked into an AMI, or pasted into a CI secret and forgotten. Roles eliminate that entire class of leak for workloads running inside AWS: there's no key to leak.

  5. 05

    CROSS-ACCOUNT access uses the same mechanism: account B creates a role whose trust policy names account A; a principal in account A assumes it. This is how organizations with separate dev/staging/prod accounts let engineers or pipelines move between them without holding separate users in each.

Code & diagrams

trust-policy-ec2.jsonjson

The TRUST policy — who may assume this role. It is separate from the PERMISSIONS policy that says what the role can do.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "ec2.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}
role-for-ec2.shbash
aws iam create-role \
  --role-name app-server \
  --assume-role-policy-document file://trust-policy-ec2.json

aws iam attach-role-policy \
  --role-name app-server \
  --policy-arn arn:aws:iam::123456789012:policy/ReadAcmeReports

# EC2 attaches roles via an instance profile wrapper
aws iam create-instance-profile --instance-profile-name app-server
aws iam add-role-to-instance-profile \
  --instance-profile-name app-server --role-name app-server

# From inside the instance — no keys configured anywhere:
aws sts get-caller-identity
# "Arn": "arn:aws:sts::123456789012:assumed-role/app-server/i-0abc..."
assume-cross-account.shbash
# Manually assume a role in another account and inspect what comes back
aws sts assume-role \
  --role-arn arn:aws:iam::999988887777:role/deployer \
  --role-session-name priya-deploy

# Returns AccessKeyId, SecretAccessKey, SessionToken, Expiration.
# Easier: let the CLI do it via a profile in ~/.aws/config
# [profile prod-deploy]
# role_arn = arn:aws:iam::999988887777:role/deployer
# source_profile = default
aws s3 ls --profile prod-deploy
AssumeRoleFlowdiagram
Rendering diagram…

Explain it without notes

01

What is the difference between a role's trust policy and its permissions policy?

02

Why is 'give the EC2 instance an IAM role' a better answer than 'put an access key in the instance's environment variables', even if the permissions granted are identical?

Practice

01

Write the trust policy for a role that only Lambda functions can assume.

02

You run aws sts get-caller-identity on an EC2 instance and get Unable to locate credentials. List two likely causes.

Trade-offs

  • ↔

    Roles remove long-lived secrets, but they add indirection: debugging 'why is this denied?' now means checking the trust policy, the permissions policy, any permission boundary, and any SCP (Topic 1.3) — and understanding which identity the SDK actually resolved.

Done when you can

  • I can explain the difference between a trust policy and a permissions policy.

  • I can attach a role to an EC2 instance through an instance profile.

  • I can assume a cross-account role from the CLI using a profile.

  • I default to roles, not access keys, for any workload running inside AWS.