# Roles: humans SSO, workloads assume, keys are the leak

Source: https://ai.techclick.in/blog_aws_iam_role_not_user_key
Markdown: https://ai.techclick.in/blog_aws_iam_role_not_user_key.md
Publisher: Techclick Infosec Pvt Ltd

Humans via Identity Center. Workloads assume roles. Long-lived IAM user keys leak. Prefer instance profile and IRSA.

## The ticket

 GuardDuty later (lesson 7) will scream about an access key from a strange ASN. Today you still see  aws_access_key_id  in the AMI’s user-data.  AppEC2Role  already exists. Nobody attached the instance profile.

  Quick interview answer

 An  IAM role  is assumed: STS issues temporary credentials. Humans:  IAM Identity Center  (SSO) → permission set → role in account  111122223333 . EC2:  instance profile  passes  AppEC2Role ; the instance retrieves creds from the metadata service (prefer IMDSv2). EKS:  IRSA  — service account annotated with a role, trust via the cluster OIDC provider. IAM user access keys are long-lived, copied, committed, and forgotten. Do not create them for people.

  Hero · no static key

 If the credential can live in a gist, it is the wrong credential.
  Lab data · dummy only
 Account  111122223333  · OUs Security / Workloads · hub VPC  10.50.0.0/16  · app VPC  10.51.0.0/16  · SG  sg-web  · NACL  acl-app  · bucket  tc-lab-app-logs  · role  AppEC2Role  · TGW  tgw-lab  · VGW public  203.0.113.60  · on-prem FortiGate WAN  203.0.113.10 . Dummy account ID. Not yours.

## Mental model

   Principal  How it assumes  What you should see

  Priya (human)  Identity Center permission set   assumed-role/AWSReservedSSO_…/priya
  EC2 in 10.51.0.0/16  Instance profile →  AppEC2Role   Instance profile attached; IMDSv2; no AKIA in user-data
  EKS pod  IRSA (service account + OIDC trust)  Role trust  sts:AssumeRoleWithWebIdentity
  IAM user + access key  Long-lived AKIA/ASIA static pair  Treat as an incident if it belongs to a person

  Assume, do not embed

  Identity Center  humans · temp creds

- AppEC2Role instance profile / IRSA STS temp IAM user key classic leak Same account. Two ways in. Only one belongs in production. https://111122223333.signin.aws.amazon.com/console Training mock · not live AWS console VPC IAM S3 CloudTrail IAM → Roles / Identity Center ### AppEC2Role + permission sets Human path IAM Identity Center · no long-lived user access keys Role AppEC2Role Trust ec2.amazonaws.com (instance profile) Permissions Least privilege to tc-lab-app-logs · no AdministratorAccess IMDSv2 Required on the instance · hop limit designed Cancel Save Workloads assume roles. Humans SSO. Training mock. ## How to choose Situation Do Do not Person needs console + CLI Identity Center permission set Create IAM user + AKIA EC2 must talk to S3 / KMS Instance profile on AppEC2Role Keys in user-data or AMI Pod must talk to AWS APIs IRSA Node role reused by every pod Third-party CI OIDC assume-role (same idea as IRSA) A forever key in the pipeline secret store “for now” ## Runbook #### Side A — humans Identity Center assignments for Priya. Delete IAM user access keys that belong to people. Credential report: look for access_key_1_active .

- #### Side B — compute Attach the instance profile to the app instance. Confirm trust policy is ec2.amazonaws.com . For EKS, annotate the service account and check the OIDC provider.

- #### Side C — prove From the instance: aws sts get-caller-identity shows AppEC2Role . curl IMDSv2, not v1. Grep user-data for AKIA — must be empty.

  aws cli · role proof  aws iam get-role --role-name AppEC2Role --query 'Role.AssumeRolePolicyDocument'

aws iam list-instance-profiles-for-role --role-name AppEC2Role

aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 --decode | head

# on the instance (dummy)
TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/AppEC2Role
aws sts get-caller-identity
# Arn: arn:aws:sts::111122223333:assumed-role/AppEC2Role/i-labapp01

## Four failures

### 1 · Keys in user-data

 Anyone with  ec2:DescribeInstanceAttribute  can read them. Next lesson is secrets. This lesson is: do not put them there.

### 2 · Role exists, profile not attached

 The instance still has no creds. Attach the instance profile, do not mint a user key as a shortcut.

### 3 · Node instance role shared by every pod

 That is not IRSA. One compromised pod is every AWS permission on the node.

### 4 · “Break-glass IAM user” with AKIA in LastPass, used daily

 That is just a human key. Identity Center + a rare root/break-glass runbook.

## How to prove it

  Close only when

 1) Humans assume Identity Center roles. 2) The instance caller is AppEC2Role. 3) Credential report shows no people-keys. 4) User-data has no secrets.

## Traps

   You hear  You say

  We need an access key for EC2  You need an instance profile
  IRSA is just the node role  IRSA is a per-service-account role via OIDC
  ASIA keys in metadata are long-lived  They are temporary session creds from STS

## Knowledge check

   Judgment items. One best answer. Reasons send you back to the matching section.

       Q1
       Preferred human access to 111122223333?

           IAM user access keys
           IAM Identity Center permission sets
           Root AKIA
           Keys in user-data

       Correct:  b . SSO for humans.

       Q2
       EC2 should get AWS credentials from…

           An instance profile on AppEC2Role
           A plaintext key in user-data
           A second root
           The NACL

       Correct:  a . Instance profile.

       Q3
       IRSA is…

           A security group
           EKS service account assuming a role via OIDC
           A NACL rule
           An S3 ACL

       Correct:  b . IAM Roles for Service Accounts.

       Q4
       Why are IAM user access keys the classic leak?

           They are short-lived by default
           They are long-lived and get committed, copied, and forgotten
           They cannot call S3
           STS refuses them

       Correct:  b . Long-lived.

       Q5
       Role exists but the instance cannot call S3. First check?

           Instance profile actually attached
           Delete CloudTrail
           Open acl-app deny
           Create root keys

       Correct:  a . Profile attach.

       Q6
       get-caller-identity on the app host should show…

           arn:...:assumed-role/AppEC2Role/...
           root
           An IAM user named deploy
           The FortiGate

       Correct:  a . Proof.

       Check answers
       Reset

  AWS security class series:   Shared + IAM  ·  Org / OU  ·  SG vs NACL  ·  Role not key  ·  KMS + Secrets  ·  VPC endpoint  ·  Trail + GuardDuty  ·  TGW hub  ·  S3 public  ·  Interview

## Sources

- IAM User Guide — IAM roles .

 Related:  AWS session factory  ·  Migration series .

---
Cite this Techclick lesson with the source URL. Do not invent fees, batch dates, or job guarantees.
Browse all lessons: https://ai.techclick.in/blogs
AI index: https://ai.techclick.in/llms.txt
