aws-bedrock-agent-swap-role

Swap a Bedrock Agent's execution role via UpdateAgent+PassRole to execute the orchestration loop as an attacker-chosen role.

derived aws emits CanExecuteAs

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanModifyConfiguration {'agent': None} {'principal': None} CanPassIdentity {'role': None}

where

node_type(?agent) == GenericCompute ?agent.provider_type == 'AWS::Bedrock::Agent' ?role trust policy allows bedrock.amazonaws.com (or is unknown -> POTENTIAL) iam:PassRole for ?role permits iam:PassedToService bedrock.amazonaws.com (or is unconditioned)

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'principal': None} CanTrigger {'agent': None}

emit

source typeIdentity
target typeIdentity
source?principal
target?role
permissionsbedrock:UpdateAgent iam:PassRole
conditionsiam_permission role_compatibility
state logicif ?role trust policy or iam:PassedToService is unknown/unresolved: POTENTIAL(role_compatibility); elif matched(optional[0]) or InvokeAgent path exists for ?agent: ACTIVE; else: CONDITIONAL(trigger_exists) — the role is bound but no run path is established yet; the agent must be invoked to realize the escalation.

Narrative

{principal.name} can update Bedrock Agent {agent.name} to run as {role.name} (bedrock:UpdateAgent + iam:PassRole to bedrock.amazonaws.com); when the Agent is invoked, its orchestration loop executes with {role.name}'s credentials, giving {principal.name} effective execution as {role.name}.

Raw rule rules/derived/aws/bedrock.yaml

id: aws-bedrock-agent-swap-role
emits: CanExecuteAs
description: Swap a Bedrock Agent's execution role via UpdateAgent+PassRole to execute the orchestration
  loop as an attacker-chosen role.
match:
- - principal: null
  - CanModifyConfiguration
  - agent: null
- - principal: null
  - CanPassIdentity
  - role: null
where:
- node_type(?agent) == GenericCompute
- ?agent.provider_type == 'AWS::Bedrock::Agent'
- ?role trust policy allows bedrock.amazonaws.com (or is unknown -> POTENTIAL)
- iam:PassRole for ?role permits iam:PassedToService bedrock.amazonaws.com (or is unconditioned)
optional:
- - principal: null
  - CanTrigger
  - agent: null
emit:
  source_type: Identity
  target_type: Identity
  source: ?principal
  target: ?role
  permissions:
  - bedrock:UpdateAgent
  - iam:PassRole
  conditions:
  - iam_permission
  - role_compatibility
  state_logic: "if ?role trust policy or iam:PassedToService is unknown/unresolved:\n  POTENTIAL(role_compatibility);\n\
    elif matched(optional[0]) or InvokeAgent path exists for ?agent:\n  ACTIVE;\nelse:\n  CONDITIONAL(trigger_exists)\
    \ \u2014 the role is bound but no run path is\n  established yet; the agent must be invoked to realize\
    \ the escalation."
  confidence: min(contributing_confidences) * 0.95
  derived_from:
  - <CanModifyConfiguration edge_id for ?principal -> ?agent>
  - <CanPassIdentity edge_id for ?principal -> ?role>
  - <CanTrigger edge_id for ?principal -> ?agent (optional)>
  false_positive_note: "Honor iam:PassedToService: a role passable only to lambda.amazonaws.com or ec2.amazonaws.com\
    \ does NOT yield a Bedrock execution role \u2014 downgrade to POTENTIAL(role_compatibility) when PassedToService\
    \ is absent or scoped to an incompatible service. The agent role trust policy must allow bedrock.amazonaws.com;\
    \ without that, CreateAgent/UpdateAgent rejects the role. An SCP denying bedrock:UpdateAgent or iam:PassRole\
    \ at the effective scope makes this BLOCKED. NOTE: This rule duplicates the provider-agnostic linchpin\
    \ execute-as-via-config-identity-swap in can-execute-as.yaml. The Bedrock-specific state_logic adds\
    \ nuance (trigger_exists gating for CONDITIONAL), but the base CanExecuteAs emission is handled by\
    \ the linchpin. Deduplication is automatic on (type=CanExecuteAs, source, target, scope)."
  narrative: '{principal.name} can update Bedrock Agent {agent.name} to run as {role.name} (bedrock:UpdateAgent
    + iam:PassRole to bedrock.amazonaws.com); when the Agent is invoked, its orchestration loop executes
    with {role.name}''s credentials, giving {principal.name} effective execution as {role.name}.'
move · open · esc close