aws-apigw-config-swap-executes-as
Changing an integration's credentials field to a more-privileged role (apigateway:PATCH + iam:PassRole) then invoking yields execution as the new role.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanModifyConfiguration {'api': None}
{'principal': None} CanPassIdentity {'role': None}
where
node_type(?api) ==
APIGateway
?role trust policy allows apigateway.amazonaws.com
iam:PassRole for ?role permits iam:PassedToService including apigateway.amazonaws.com (or unconditioned)
optional
Present → upgrade the emitted state; absent → downgrade (not a hard requirement).
{'principal': None}
CanInvoke {'api': None}
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | ?principal |
| target | ?role |
| permissions | apigateway:PATCH iam:PassRole execute-api:Invoke? |
| conditions | role_compatibility iam_permission |
| state logic | ACTIVE when the principal can both modify the integration (apigateway:PATCH on the integration resource) and pass the target role to apigateway.amazonaws.com (iam:PassRole with iam:PassedToService including apigateway.amazonaws.com or unconditioned), AND the principal can also invoke the API (execute-api:Invoke — matched optional[0]). CONDITIONAL(trigger_exists) when the principal cannot invoke but the API is reachable by another caller or has a public endpoint. POTENTIAL (role_compatibility) when the role trust or iam:PassedToService is unknown/unresolved. |
Narrative
{principal.name} can modify {api.name}'s integration configuration (apigateway:PATCH) and pass IAM role {role.name} to apigateway.amazonaws.com (iam:PassRole); by swapping the integration's credentials to {role.name} and then invoking the API, {principal.name} executes the integration as {role.name}.
Raw rule rules/derived/aws/apigateway.yaml
id: aws-apigw-config-swap-executes-as
emits: CanExecuteAs
description: Changing an integration's credentials field to a more-privileged role (apigateway:PATCH +
iam:PassRole) then invoking yields execution as the new role.
match:
- - principal: null
- CanModifyConfiguration
- api: null
- - principal: null
- CanPassIdentity
- role: null
where:
- node_type(?api) == APIGateway
- ?role trust policy allows apigateway.amazonaws.com
- iam:PassRole for ?role permits iam:PassedToService including apigateway.amazonaws.com (or unconditioned)
optional:
- - principal: null
- CanInvoke
- api: null
emit:
source_type: Identity
target_type: Identity
source: ?principal
target: ?role
permissions:
- apigateway:PATCH
- iam:PassRole
- execute-api:Invoke?
conditions:
- role_compatibility
- iam_permission
state_logic: "ACTIVE when the principal can both modify the integration (apigateway:PATCH on the integration\
\ resource) and pass the target role to apigateway.amazonaws.com (iam:PassRole with iam:PassedToService\
\ including apigateway.amazonaws.com or unconditioned), AND the principal can also invoke the API\
\ (execute-api:Invoke \u2014 matched optional[0]). CONDITIONAL(trigger_exists) when the principal\
\ cannot invoke but the API is reachable by another caller or has a public endpoint. POTENTIAL (role_compatibility)\
\ when the role trust or iam:PassedToService is unknown/unresolved."
confidence: min(contributing_confidences) * 0.9
derived_from:
- ?principal CanModifyConfiguration ?api
- ?principal CanPassIdentity ?role
- ?principal CanInvoke ?api (optional)
false_positive_note: "Honor iam:PassedToService: a role passable only to ec2/ecs does NOT yield API\
\ Gateway execution. The role MUST trust apigateway.amazonaws.com or sts:AssumeRole fails \u2014 downgrade\
\ to POTENTIAL(role_compatibility) when trust is unknown. The CanModifyConfiguration must reach the\
\ integration resource specifically (apigateway:PATCH on /restapis/{id}/resources/{rid}/methods/{method}/integration\
\ or the V2 equivalent), not merely the stage or API root. An SCP/permission-boundary denying apigateway:PATCH\
\ or iam:PassRole blocks this. CITE can-execute-as.yaml execute-as-via-config-identity-swap for the\
\ general pattern; this rule adds the API-Gateway-specific PassedToService gate and the two-step (swap\
\ + invoke) mechanics."
narrative: '{principal.name} can modify {api.name}''s integration configuration (apigateway:PATCH) and
pass IAM role {role.name} to apigateway.amazonaws.com (iam:PassRole); by swapping the integration''s
credentials to {role.name} and then invoking the API, {principal.name} executes the integration as
{role.name}.'