6.4 Instance Profiles, Service Roles & Execution Roles for Compute
Key Takeaways
EC2 instances get role credentials from IMDS through an instance profile; require IMDSv2 to block SSRF-based credential theft.
iam:PassRole, scoped by role ARN and the iam:PassedToService condition, controls who can attach roles to compute services.
In Amazon ECS the task role serves the application, while the task execution role pulls images, writes logs, and retrieves referenced secrets.
EKS Pod Identity roles trust pods.eks.amazonaws.com, work across clusters without trust-policy edits, and add session tags; IRSA trusts each cluster's OIDC provider.
Trust policies for service principals should use aws:SourceArn and aws:SourceAccount to prevent the confused deputy problem.
6.4 Instance Profiles, Service Roles & Execution Roles for Compute
Every compute workload that calls an AWS API needs credentials. Skill 3.2.2 tests whether you give them the right kind: temporary credentials from an IAM role, delivered by the platform, scoped to that workload, and never embedded in code, AMIs, container images, or environment files. Each compute service delivers role credentials differently, and most exam traps come from mixing them up.
The Roles Each Compute Service Uses
| Compute Service | Role Mechanism | Trusted Service Principal | How Code Gets Credentials |
|---|---|---|---|
| Amazon EC2 | Instance profile containing one IAM role | ec2.amazonaws.com | Instance Metadata Service (IMDS) |
| AWS Lambda | Execution role | lambda.amazonaws.com | Environment variables injected into the runtime |
| Amazon ECS task | Task role (application) and task execution role (agent) | ecs-tasks.amazonaws.com | Container credentials endpoint for the task role |
| Amazon EKS pod | EKS Pod Identity or IAM roles for service accounts (IRSA) | pods.eks.amazonaws.com, or the cluster's OIDC provider | Pod Identity Agent, or a projected service account token exchanged with STS |
| Other services (Glue, Step Functions, SageMaker AI, CodeBuild) | Service role | The service's principal | Assumed by the service on your behalf |
EC2 Instance Profiles and IMDS
An instance profile is a container for one IAM role. When it is attached, code on the instance retrieves short-term credentials from the Instance Metadata Service, and the credentials rotate automatically.
- Require IMDSv2. IMDSv2 requires a session token obtained with a
PUTrequest (the token lifetime is 1 second to 6 hours) before metadata can be read, which blocks most server-side request forgery (SSRF) attempts to steal role credentials. SetHttpTokenstorequiredon instances and launch templates, and enforce it with an SCP on theec2:MetadataHttpTokenscondition key or a declarative policy for instance metadata defaults. - Control the hop limit.
HttpPutResponseHopLimitof 1 stops containers that sit an extra network hop away from reaching IMDS, which forces them to use their own task or pod credentials. - Detect credential theft. GuardDuty reports
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS(and.InsideAWS) when an instance's role credentials are used from somewhere other than that instance. - Bind credentials to the network. The global condition keys
aws:EC2InstanceSourceVPCandaws:EC2InstanceSourcePrivateIPv4identify where instance credentials were delivered. Comparingaws:EC2InstanceSourceVPCwithaws:SourceVpcin an SCP or resource policy lets instance credentials work only from their own VPC.
iam:PassRole: Who Can Hand a Role to a Service
Attaching a role to an EC2 instance, Lambda function, ECS task, or other service requires the caller to have iam:PassRole on that role. If a developer can pass any role, they can launch compute with an administrator role and run code as that role, which is privilege escalation. Restrict iam:PassRole to specific role ARNs or paths and use the iam:PassedToService condition:
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::111122223333:role/app-roles/lambda-*",
"Condition": {
"StringEquals": { "iam:PassedToService": "lambda.amazonaws.com" }
}
}
Service Roles, Service-Linked Roles & the Confused Deputy
- A service role is a role you create and control that a service assumes to act for you, such as a Glue job role or a Step Functions state machine role.
- A service-linked role is predefined by the service, linked to it, and not editable; SCPs don't restrict service-linked roles.
- When a service principal assumes your role on behalf of a specific resource, add
aws:SourceArnandaws:SourceAccountconditions to the trust policy. This prevents the confused deputy problem, where another customer's resource tricks the service into using your role.
Lambda Execution Roles
The execution role grants the function's permissions. Lambda assumes it and injects the credentials as environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN), so never log the environment. Separate this from the function's resource-based policy, which controls who may invoke the function. The execution role should include only the function's needs; functions attached to a VPC also need permissions to manage network interfaces (for example, the AWSLambdaVPCAccessExecutionRole managed policy).
ECS: Task Role vs Task Execution Role
This distinction appears on the exam often:
- The task role is what the application code in the container uses (for example,
dynamodb:PutItem). Credentials come from the container credentials endpoint, not the EC2 instance profile. - The task execution role is used by the ECS agent and Fargate to pull images from Amazon ECR, send container logs to CloudWatch Logs, and retrieve Secrets Manager or Parameter Store values referenced in the task definition.
If an application gets AccessDenied calling DynamoDB, check the task role; if the task fails to start because it can't pull an image or read a secret, check the task execution role.
EKS: Pod Identity and IRSA
Pods should never share the node's instance profile. Two mechanisms give each Kubernetes service account its own role:
| Feature | EKS Pod Identity | IAM Roles for Service Accounts (IRSA) |
|---|---|---|
| Setup | Create a pod identity association in the EKS API; run the EKS Pod Identity Agent add-on | Create an IAM OIDC provider for each cluster |
| Role trust policy | Trusts pods.eks.amazonaws.com for sts:AssumeRole and sts:TagSession | Trusts the cluster's OIDC provider, with conditions on sub (system:serviceaccount:<namespace>:<name>) and aud |
| Reuse across clusters | Same role works in many clusters without editing the trust policy | Trust policy must list each cluster's OIDC provider |
| ABAC | Adds session tags such as cluster name, namespace, and service account | No automatic session tags |
Separately, EKS access entries map IAM principals to Kubernetes permissions through the EKS API (with access policies such as cluster admin or view), replacing hand-edited aws-auth ConfigMap entries.
Specialty Exam Pitfalls
- Long-term keys in user data or images: Access keys baked into AMIs, containers, or user data are exposed to anyone who can read them. Use roles.
- IMDSv1 left enabled: SSRF against an application can read instance credentials; require IMDSv2.
- Unrestricted
iam:PassRole: Lets users launch compute with privileged roles. - Confusing ECS roles: Application permissions belong in the task role, not the task execution role or the container instance's instance profile.
- Pods using the node role: Without Pod Identity or IRSA, and with IMDS reachable, every pod inherits the node's permissions.
A containerized application on Amazon ECS with AWS Fargate fails to start. The ECS console shows the error 'unable to pull secrets or registry auth' when the task tries to retrieve a database password referenced from AWS Secrets Manager in the task definition. The application's own calls to Amazon DynamoDB worked in a previous deployment. Which role most likely needs to be fixed?
The task execution role, which the ECS agent uses to pull images and retrieve secrets referenced in the task definition.
The task role, which the application uses for its DynamoDB calls.
The instance profile of the Fargate host.
The ECS service-linked role, which must be edited to add secretsmanager:GetSecretValue.
A security review finds that developers can create Lambda functions and attach any IAM role in the account, including an administrator role. The team wants developers to keep deploying functions but only with roles under the path /app-roles/ and only to Lambda. Which control addresses the privilege escalation risk?
Add a permissions boundary to the administrator role.
Enable GuardDuty Lambda Protection.
Restrict iam:PassRole in the developers' policy to arn:aws:iam::111122223333:role/app-roles/* with the condition iam:PassedToService equal to lambda.amazonaws.com.
Require MFA for the lambda:CreateFunction action.
A platform team runs 30 Amazon EKS clusters. Each application's service account needs its own IAM role, and the team wants to reuse the same role across clusters without editing trust policies whenever a new cluster is created. The team also wants session tags with the cluster name and namespace for attribute-based access control. Which approach meets these requirements?
Attach a broad instance profile to all worker nodes and filter access with Kubernetes RBAC.
Use EKS Pod Identity: install the Pod Identity Agent, create pod identity associations, and have each role trust pods.eks.amazonaws.com for sts:AssumeRole and sts:TagSession.
Use IAM roles for service accounts, adding every cluster's OIDC provider to every role's trust policy.
Store access keys for each application in a Kubernetes secret.
GuardDuty reports UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS for a role attached to a web server's instance profile. The web application had a server-side request forgery flaw, and the instance still allows IMDSv1. Which combination of actions best contains the incident and prevents a recurrence?
Delete the instance profile and store access keys in the application configuration file instead.
Rotate the IAM role's access keys and disable GuardDuty findings for this role.
Increase the metadata hop limit to 5 and keep IMDSv1 enabled for compatibility.
Revoke the role's active sessions (for example, with a deny on aws:TokenIssueTime), require IMDSv2 on the instance and in launch templates, and fix the SSRF flaw.
Sections you finish are checked off in the contents.