Security Considerations for Using IAM PassRole with Compute Services
Granting iam:PassRole without resource constraints enables privilege escalation by allowing principals to hand off any IAM role—including administrator roles—to AWS compute services like Lambda, ECS, and Step Functions.
The iam:PassRole permission is a cross-service IAM action that lets a principal hand off an existing IAM role to another AWS service for resource creation. When misconfigured with "Resource": "*", it becomes a direct privilege escalation vector, as documented in the Agent Toolkit for AWS. Understanding how to scope this permission securely is essential when orchestrating workflows across compute services.
Why Unscoped IAM PassRole Permissions Are Dangerous
The Agent Toolkit for AWS explicitly warns that granting iam:PassRole with "Resource": "*" on any compute service directly enables privilege escalation. According to the core IAM skill documentation in skills/core-skills/aws-iam/SKILL.md (line 90), an overly permissive PassRole permission allows a user who can invoke a compute service to cause that service to act with any role the user can pass, including administrator-level roles.
This vulnerability chain works as follows: a principal with iam:PassRole on * plus permission to create or update a compute resource (such as lambda:CreateFunction or ecs:RunTask) can force the service to assume high-privilege roles, effectively escalating their own permissions.
Compute Services Requiring IAM PassRole
The Agent Toolkit identifies several AWS compute services that require iam:PassRole when creating or updating resources that assume execution roles:
| Compute Service | Typical API Operations | Required PassRole Pattern |
|---|---|---|
| Lambda | lambda:CreateFunction, lambda:UpdateFunctionConfiguration |
Pass specific execution role ARN to Lambda service |
| ECS | ecs:RunTask (often via Step Functions) |
Pass both task execution role and task role ARNs to ECS |
| Step Functions | states:StartExecution |
Pass roles to downstream services orchestrated by the state machine |
| Glue, SageMaker, CloudFormation | Various resource-creation APIs | Pass service-linked or custom execution roles |
Implementation details for these patterns are documented in skills/core-skills/aws-iam/SKILL.md and the specialized Step Functions skill at skills/specialized-skills/serverless-skills/processing-s3-uploads-with-step-functions/references/iam-roles.md.
Five Safeguards for Secure IAM PassRole Usage
To mitigate privilege escalation risks when using iam:PassRole with compute services, the Agent Toolkit recommends these specific controls:
-
Scope the Resource – Restrict the permission to the exact role ARN(s) required by the workflow (e.g.,
arn:aws:iam::123456789012:role/sfn-ecs-task-role). -
Use
iam:PassedToServicecondition – Bind the permission to the service that will assume the role (e.g.,"iam:PassedToService": "ecs-tasks.amazonaws.com"). -
Apply least-privilege principle – Only attach policies to the identity that needs to start the compute resource; avoid attaching to broad groups or root users.
-
Audit and monitor – Enable CloudTrail logs for
PassRoleevents and set CloudWatch alarms on failedPassRoleattempts. -
Document trust policies – Ensure the target role’s trust policy allows the specific service principal (e.g.,
ecs-tasks.amazonaws.com) and limits the source account if necessary.
Implementing Scoped IAM PassRole Policies
Step Functions to ECS PassRole Policy
When orchestrating ECS tasks from Step Functions, you must scope iam:PassRole to only the specific task roles. This example from skills/specialized-skills/serverless-skills/processing-s3-uploads-with-step-functions/references/iam-roles.md (lines 75-80) demonstrates the correct pattern:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": [
"arn:aws:iam::123456789012:role/sfn-ecs-execution-role",
"arn:aws:iam::123456789012:role/sfn-ecs-task-role"
],
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"ecs-tasks.amazonaws.com",
"ecs.amazonaws.com"
]
}
}
}
]
}
Trust Policy for Step Functions Service Role
The Step Functions service role itself requires a trust policy that allows the Step Functions principal to assume it. This configuration is referenced in iam-roles.md (lines 9-12):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "states.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
Creating Roles via AWS CLI
To implement these policies via the command line, use the following workflow from iam-roles.md (lines 54-61):
# Create the Step Functions role
aws iam create-role \
--role-name sfn-state-machine-role \
--assume-role-policy-document file:///tmp/stepfunctions-trust-policy.json
# Attach the scoped PassRole policy
aws iam put-role-policy \
--role-name sfn-state-machine-role \
--policy-name sfn-passrole-policy \
--policy-document file://passrole-policy.json
Monitoring IAM PassRole Events
To detect unauthorized attempts or configuration errors, audit PassRole events using CloudTrail. The Step Functions skill documentation (lines 313-315 of SKILL.md) provides this query pattern:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=PassRole \
--start-time $(date -d '-7 days' +%Y-%m-%dT%H:%M:%SZ) \
--max-results 50
Set CloudWatch alarms on failed PassRole attempts to receive immediate notification of potential privilege escalation attempts.
Summary
- Never grant
iam:PassRolewith"Resource": "*"on compute services, as this creates a privilege escalation vector allowing any role to be passed to any service. - Always scope
PassRolepermissions to specific role ARNs and use theiam:PassedToServicecondition key to restrict which service can assume the role. - Lambda, ECS, and Step Functions are common compute services requiring
PassRolefor execution roles, with patterns documented in the Agent Toolkit for AWS core IAM and Step Functions skills. - Monitor CloudTrail for
PassRoleevents to detect unauthorized usage or configuration errors. - Reference the canonical examples in
skills/specialized-skills/serverless-skills/processing-s3-uploads-with-step-functions/references/iam-roles.mdfor production-ready policies.
Frequently Asked Questions
What is the principal risk of using iam:PassRole with Resource: "*"?
Granting iam:PassRole with a wildcard resource allows any principal to pass any IAM role—including administrator roles—to AWS compute services. Combined with permissions to create or update resources (like lambda:CreateFunction), this enables privilege escalation where a user can force a service to assume high-privilege roles and perform actions beyond their own permissions.
Which AWS services commonly require iam:PassRole?
Common compute services requiring iam:PassRole include Lambda (for execution roles), ECS (for task and task execution roles), Step Functions (for roles passed to downstream services), Glue, SageMaker, and CloudFormation. Each service assumes the passed role to perform operations on your behalf.
How do I restrict which service can assume a passed role?
Use the iam:PassedToService condition key in your IAM policy. For example, include "Condition": { "StringEquals": { "iam:PassedToService": "ecs-tasks.amazonaws.com" } } to ensure the role can only be passed to ECS tasks, preventing it from being passed to Lambda or other services if the principal has broader permissions.
How can I audit who is using iam:PassRole in my account?
Enable AWS CloudTrail and query for PassRole events using lookup-events with AttributeKey=EventName,AttributeValue=PassRole. Analyze these logs to identify which roles are being passed, by whom, and to which services. Set CloudWatch alarms on failed PassRole attempts to detect potential configuration errors or unauthorized access attempts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →