aws-ssm-cross-account-sendcommand-enter-account

A principal in account A that can execute commands on an instance in account B, which runs as a role in account B, gains a foothold in account B.

derived aws emits CanEnterAccount

match

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

{'principal': None} CanExecuteCommand {'instance': None} {'instance': None} ExecutesAs {'role': None}

where

node_type(?instance) == VirtualMachine ?principal.account != ?instance.account # cross-account execution ?instance.account == ?role.account # role lives in the instance's account

emit

source typeIdentity
target typeAccount
source?principal
target<Account boundary node that Contains ?instance>
conditionsresource_policy iam_permission service_state
state logicACTIVE when the CanExecuteCommand edge is ACTIVE (principal's ssm:SendCommand or ssm:StartSession is EFFECTIVE on the instance ARN cross-account, the instance is Online, and any cross-account resource policy / IAM trust permits the call); CONDITIONAL(resource_policy) when the cross-account permission is present but not fully confirmed (e.g. the remote-account resource policy or IAM role granting the cross-account ssm access is not yet modeled); BLOCKED when an SCP in account B denies ssm:SendCommand from external accounts.

Narrative

{principal.name} (account {principal.account}) can execute commands on {instance.name} (account {instance.account}) via SSM, and that instance runs as {role.name} in account {instance.account}, giving {principal.name} a credential foothold in account {instance.account}.

Raw rule rules/derived/aws/ssm.yaml

id: aws-ssm-cross-account-sendcommand-enter-account
emits: CanEnterAccount
description: A principal in account A that can execute commands on an instance in account B, which runs
  as a role in account B, gains a foothold in account B.
match:
- - principal: null
  - CanExecuteCommand
  - instance: null
- - instance: null
  - ExecutesAs
  - role: null
where:
- node_type(?instance) == VirtualMachine
- '?principal.account != ?instance.account  # cross-account execution'
- '?instance.account == ?role.account        # role lives in the instance''s account'
emit:
  source_type: Identity
  target_type: Account
  source: ?principal
  target: <Account boundary node that Contains ?instance>
  permissions: []
  conditions:
  - resource_policy
  - iam_permission
  - service_state
  state_logic: ACTIVE when the CanExecuteCommand edge is ACTIVE (principal's ssm:SendCommand or ssm:StartSession
    is EFFECTIVE on the instance ARN cross-account, the instance is Online, and any cross-account resource
    policy / IAM trust permits the call); CONDITIONAL(resource_policy) when the cross-account permission
    is present but not fully confirmed (e.g. the remote-account resource policy or IAM role granting the
    cross-account ssm access is not yet modeled); BLOCKED when an SCP in account B denies ssm:SendCommand
    from external accounts.
  confidence: 0.88
  derived_from:
  - ?principal CanExecuteCommand ?instance
  - ?instance ExecutesAs ?role (cross-account)
  false_positive_note: Cross-account SSM command execution requires the caller's IAM policy to permit
    ssm:SendCommand on the target instance ARN in account B, AND account B's IAM / resource policy must
    allow it (typically a cross-account IAM role with ssm:SendCommand + ec2:DescribeInstances that the
    caller assumes, or an instance-level resource policy if supported). A principal in account A using
    their own identity to SendCommand to account B's instance directly is uncommon and requires explicit
    account-B-side permission; more typical is assuming a cross-account role in account B first (CanAssume
    -> CanEnterAccount). Only emit when the cross-account permission is confirmed.
  narrative: '{principal.name} (account {principal.account}) can execute commands on {instance.name} (account
    {instance.account}) via SSM, and that instance runs as {role.name} in account {instance.account},
    giving {principal.name} a credential foothold in account {instance.account}.'
move · open · esc close