IAM Passrole
Identity and Access Management
AWS
Cloud Security
Role Management

Understanding IAM Passrole

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

iam:PassRole is one of the most misunderstood AWS permissions because it does not grant direct access to a service API. Instead, it controls whether a principal is allowed to configure an AWS service to use a specific IAM role on that principal's behalf.

What iam:PassRole Really Means

When you create or update resources such as Lambda functions, EC2 instances, or Step Functions state machines, you often provide a role ARN. That role gives the AWS service permissions to call other AWS APIs later.

iam:PassRole is the guardrail on that handoff.

If a user can pass an overly powerful role to a service, the service may end up doing actions the user should not have been able to trigger indirectly. That is why iam:PassRole is security-sensitive even though it looks like a small helper permission.

The Three Pieces That Must Align

For role passing to work, three conditions have to be true.

First, the caller must be allowed to pass the role.

Second, the role itself must trust the target AWS service through its trust policy.

Third, the service API must actually accept that role as part of the resource configuration.

A minimal identity policy for the caller often looks like this.

json
1{
2  "Version": "2012-10-17",
3  "Statement": [
4    {
5      "Effect": "Allow",
6      "Action": [
7        "iam:GetRole",
8        "iam:PassRole"
9      ],
10      "Resource": "arn:aws:iam::111122223333:role/app-lambda-exec-role"
11    }
12  ]
13}

The role being passed also needs a trust relationship that allows the service to assume it.

json
1{
2  "Version": "2012-10-17",
3  "Statement": [
4    {
5      "Effect": "Allow",
6      "Principal": {
7        "Service": "lambda.amazonaws.com"
8      },
9      "Action": "sts:AssumeRole"
10    }
11  ]
12}

Without both policies, the configuration will fail or the service will be unable to assume the role.

A Concrete Example With Lambda

Suppose a deployment role creates Lambda functions. The deployment role does not need permission to write CloudWatch logs itself, but the Lambda execution role does.

The deployment role needs permission to call lambda:CreateFunction and permission to pass the specific execution role.

bash
1aws lambda create-function \
2  --function-name demo-passrole \
3  --runtime python3.12 \
4  --handler app.lambda_handler \
5  --zip-file fileb://function.zip \
6  --role arn:aws:iam::111122223333:role/app-lambda-exec-role

At that moment, AWS checks whether the caller can pass app-lambda-exec-role. Later, when the function runs, Lambda assumes that role and uses its permissions.

That separation matters. iam:PassRole governs setup time. The role permissions govern runtime.

Scope It Tightly

The most important rule is to avoid "Resource": "*" for iam:PassRole. If you allow every role, you make privilege escalation much easier.

A better approach is to allow only a narrow set of approved roles, often by exact ARN or controlled naming pattern.

You can also restrict which AWS service can receive the role by using the iam:PassedToService condition key.

json
1{
2  "Version": "2012-10-17",
3  "Statement": [
4    {
5      "Effect": "Allow",
6      "Action": "iam:PassRole",
7      "Resource": "arn:aws:iam::111122223333:role/app-*",
8      "Condition": {
9        "StringEquals": {
10          "iam:PassedToService": "lambda.amazonaws.com"
11        }
12      }
13    }
14  ]
15}

That policy means the principal may pass approved app- roles, but only to Lambda.

Important Limits

AWS documents two limits that catch people off guard.

One is account scope. You can only use iam:PassRole to pass a role to a service in the same AWS account. Cross-account patterns require an intermediate role setup, not direct passing.

The other is observability. iam:PassRole is not a standalone API call, so it does not appear in CloudTrail as its own event. To audit it, inspect the service API event that created or updated the resource receiving the role, such as CreateFunction for Lambda.

Common Pitfalls

The most common mistake is granting iam:PassRole on all roles. That turns many ordinary deployment permissions into privilege-escalation paths.

Another mistake is forgetting the trust policy. Even if the caller can pass the role, the service cannot use it unless the trust relationship names the correct service principal.

A third issue is assuming iam:PassRole lets the caller assume the role directly. It does not. Direct assumption uses sts:AssumeRole, which is a different permission path.

Finally, be careful with service-linked roles. Some AWS services create and manage them automatically. If you explicitly specify one, iam:PassRole may be required even though the service could have created the default role for you.

Summary

  • 'iam:PassRole controls whether a principal may attach a role to an AWS service.'
  • It matters at configuration time, not at the moment the service later uses the role.
  • Safe use requires a caller policy, a correct trust policy, and a supported service API.
  • Scope the permission to specific role ARNs whenever possible.
  • Use iam:PassedToService to restrict which service can receive the role.
  • Treat broad PassRole permissions as a security risk, not as routine convenience.

Course illustration
Course illustration

All Rights Reserved.