aws-ebs-snapshot-exposes-credential

Reading snapshot data (CanReadData) that contains secrets (ContainsSecret) lets the principal extract and authenticate as the identity those secrets belong to - shorthand for the CanReadData → ContainsSecret → CredentialsFor chain into the CanReadSecret pivot. This rule feeds credential-chains.yaml: read-secret-yields-identity.

derived aws emits CanReadSecret

match

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

{'principal': None} CanReadData {'snapshot': None} {'snapshot': None} ContainsSecret {'secret': None}

where

node_type(?snapshot) == Snapshot node_type(?secret) == Secret

emit

source typeIdentity
target typeSecret
source?principal
target?secret
permissionsebs:GetSnapshotBlock ebs:ListSnapshotBlocks
conditionsiam_permission key_permission
state logicinherit_weakest(CanReadData, ContainsSecret): if CanReadData is CONDITIONAL (key_permission gate), then CONDITIONAL(key_permission); if ContainsSecret is POTENTIAL, then POTENTIAL (no one can read the data until forensic scan confirms the secret exists). Strongest case: ACTIVE only when both CanReadData is ACTIVE and ContainsSecret is ACTIVE. For path-finding into credential- chains.yaml:read-secret-yields-identity, this edge must be ACTIVE to unlock impersonation; POTENTIAL/CONDITIONAL contributions stall the chain.

Narrative

{principal.name} can read the data stored in {snapshot.name} (via ebs:GetSnapshotBlock or volume mount), which contains credentials for {secret.name}. Reading the snapshot allows {principal.name} to extract and use the secret, feeding into the credential escalation chain (CanImpersonateCanEscalateTo).

Raw rule rules/derived/aws/ebs.yaml

id: aws-ebs-snapshot-exposes-credential
emits: CanReadSecret
description: "Reading snapshot data (CanReadData) that contains secrets (ContainsSecret) lets the principal\
  \ extract and authenticate as the identity those secrets belong to \u2014 shorthand for the CanReadData\
  \ \u2192 ContainsSecret \u2192 CredentialsFor chain into the CanReadSecret pivot. This rule feeds credential-chains.yaml:\
  \ read-secret-yields-identity."
match:
- - principal: null
  - CanReadData
  - snapshot: null
- - snapshot: null
  - ContainsSecret
  - secret: null
where:
- node_type(?snapshot) == Snapshot
- node_type(?secret) == Secret
emit:
  source_type: Identity
  target_type: Secret
  source: ?principal
  target: ?secret
  permissions:
  - ebs:GetSnapshotBlock
  - ebs:ListSnapshotBlocks
  conditions:
  - iam_permission
  - key_permission
  state_logic: 'inherit_weakest(CanReadData, ContainsSecret): if CanReadData is CONDITIONAL (key_permission
    gate), then CONDITIONAL(key_permission); if ContainsSecret is POTENTIAL, then POTENTIAL (no one can
    read the data until forensic scan confirms the secret exists). Strongest case: ACTIVE only when both
    CanReadData is ACTIVE and ContainsSecret is ACTIVE. For path-finding into credential- chains.yaml:read-secret-yields-identity,
    this edge must be ACTIVE to unlock impersonation; POTENTIAL/CONDITIONAL contributions stall the chain.'
  confidence: min(CanReadData.confidence, ContainsSecret.confidence)
  derived_from:
  - ?principal CanReadData ?snapshot
  - ?snapshot ContainsSecret ?secret
  linchpin_citations:
  - "credential-chains.yaml:read-secret-yields-identity (consumes CanReadSecret \u2192 CanImpersonate\
    \ \u2192 CanEscalateTo)"
  false_positive_note: This rule links data access to credential extraction, feeding the credential chain.
    It is only valuable when ContainsSecret is confirmed ACTIVE (via forensic evidence in /rules/explicit/aws-ebs.yaml,
    not just structural probability). When ContainsSecret is not present or is unconfirmed, this chain
    does not emit. The permissions list shows the EBS direct API permissions (ebs:GetSnapshotBlock); the
    secret's CanReadSecret is derived from the data-read capability, not a separate IAM action. This CanReadSecret
    edge is the input to credential-chains.yaml:read-secret-yields-identity, which then chains into CanImpersonate
    and CanEscalateTo.
  narrative: "{principal.name} can read the data stored in {snapshot.name} (via ebs:GetSnapshotBlock or\
    \ volume mount), which contains credentials for {secret.name}. Reading the snapshot allows {principal.name}\
    \ to extract and use the secret, feeding into the credential escalation chain (CanImpersonate \u2192\
    \ CanEscalateTo)."
move · open · esc close