aws-lightsail-imds-token-exposure

A Lightsail instance with an associated IAM role exposes that role's session via IMDS.

derived aws emits CanRetrieveToken

match

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

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

where

node_type(?instance) == VirtualMachine provider_type(?instance) == 'AWS::Lightsail::Instance' node_type(?role) == Role a role is associated with the instance (ExecutesAs present)

emit

source<Lightsail instance>
target<associated IAM role>
conditionsservice_state

Narrative

Instance {instance.name} exposes {role.name} session credentials via the metadata service (169.254.169.254).

Raw rule rules/derived/aws/lightsail.yaml

id: aws-lightsail-imds-token-exposure
emits: CanRetrieveToken
description: A Lightsail instance with an associated IAM role exposes that role's session via IMDS.
match:
- - instance: null
  - ExecutesAs
  - role: null
where:
- node_type(?instance) == VirtualMachine
- provider_type(?instance) == 'AWS::Lightsail::Instance'
- node_type(?role) == Role
- a role is associated with the instance (ExecutesAs present)
emit:
  source: <Lightsail instance>
  target: <associated IAM role>
  permissions: []
  conditions:
  - service_state
  false_positive_note: 'Pure fact edge: the instance can mint the associated role''s session via IMDS.
    Only emit if a role is ACTUALLY associated with the instance; a Lightsail instance with no associated
    role runs as no AWS identity - do not assume one exists. The OS-access / IMDSv2-session precondition
    lives entirely in aws-lightsail-execute-as-via-instance-imds; do not duplicate it here or walk both
    as independent hops for the same role.'
  narrative: Instance {instance.name} exposes {role.name} session credentials via the metadata service
    (169.254.169.254).
move · open · esc close