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.

derived aws emits CanExecuteAs

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 typeIdentity
target typeIdentity
source?principal
target?role
permissionsapigateway:PATCH iam:PassRole execute-api:Invoke?
conditionsrole_compatibility iam_permission
state logicACTIVE 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}.'
move · open · esc close