aws-apprunner-pass-instance-role
iam:PassRole scoped to App Runner lets a principal attach an instance/access role.
match (effective permission)
{
"action": "iam:PassRole",
"resource_type": "AWS::IAM::Role"
}
where
role trust policy allows tasks.apprunner.amazonaws.com (instance role) or build.apprunner.amazonaws.com (access role)
iam:PassedToService condition (if present) includes tasks.apprunner.amazonaws.com / build.apprunner.amazonaws.com / apprunner.amazonaws.com
emit
| source type | Identity |
|---|---|
| source | <principal> |
| target | <IAM role passable to App Runner> |
| permissions | iam:PassRole |
| conditions | iam_permission role_compatibility condition_expression |
Narrative
{principal.name} can pass {role.name} to App Runner (iam:PassRole; PassedToService tasks.apprunner.amazonaws.com).
Raw rule rules/derived/aws/apprunner.yaml
id: aws-apprunner-pass-instance-role
emits: CanPassIdentity
description: iam:PassRole scoped to App Runner lets a principal attach an instance/access role.
match_effective_permission:
action: iam:PassRole
resource_type: AWS::IAM::Role
where:
- role trust policy allows tasks.apprunner.amazonaws.com (instance role) or build.apprunner.amazonaws.com
(access role)
- iam:PassedToService condition (if present) includes tasks.apprunner.amazonaws.com / build.apprunner.amazonaws.com
/ apprunner.amazonaws.com
emit:
source_type: Identity
source: <principal>
target: <IAM role passable to App Runner>
permissions:
- iam:PassRole
conditions:
- iam_permission
- role_compatibility
- condition_expression
false_positive_note: 'Honor iam:PassedToService. A role passable only to a non-App-Runner service (e.g.
ec2.amazonaws.com) yields NO App Runner execution. Also honor any apprunner:ServiceArn / aws:ResourceTag
conditions on the grant. DISTINGUISH the two App Runner role trusts: only a role whose trust allows
tasks.apprunner.amazonaws.com (the INSTANCE role / ExecutesAs identity) can yield CanExecuteAs downstream.
A CanPassIdentity emitted for a role trusting ONLY build.apprunner.amazonaws.com (the ACCESS role)
is BUILD-TIME image-pull only: it satisfies CanPassIdentity but can NEVER satisfy the tasks.apprunner
where-clause in any executeas/create-workload rule, so it must not be treated as an execution path.
Where possible, tag/split the emitted CanPassIdentity by trust principal (instance vs access) so downstream
rules only consume the instance-role variant. This mirrors the ExecutesAs false_positive_note that
already excludes the access role.
'
narrative: '{principal.name} can pass {role.name} to App Runner (iam:PassRole; PassedToService tasks.apprunner.amazonaws.com).'