aws-s3-read-data-contains-secret-yields-read-secret

A principal that can read a bucket's data (CanReadData) and the bucket contains secrets (ContainsSecret) can read those secrets via s3:GetObject.

derived aws emits CanReadSecret

match

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

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

where

node_type(?bucket) == ObjectStorage ?bucket.provider_type == 'AWS::S3::Bucket'

emit

source typeIdentity
target typeSecret
source?principal
target?secret
permissionss3:GetObject
conditionsiam_permission resource_policy
state logicinherit_weakest(CanReadData, ContainsSecret): if either contributor is CONDITIONAL or BLOCKED, inherit that state. ACTIVE only when both CanReadData and ContainsSecret are ACTIVE. The edge carries the same key_permission gate as the CanReadData input if the bucket uses SSE-KMS.

Narrative

{principal.name} can read {bucket.name} (s3:GetObject) and the bucket contains secrets ({secret.name}); reading the bucket yields the secret material.

Raw rule rules/derived/aws/s3.yaml

id: aws-s3-read-data-contains-secret-yields-read-secret
emits: CanReadSecret
description: A principal that can read a bucket's data (CanReadData) and the bucket contains secrets (ContainsSecret)
  can read those secrets via s3:GetObject.
match:
- - principal: null
  - CanReadData
  - bucket: null
- - bucket: null
  - ContainsSecret
  - secret: null
where:
- node_type(?bucket) == ObjectStorage
- ?bucket.provider_type == 'AWS::S3::Bucket'
emit:
  source_type: Identity
  target_type: Secret
  source: ?principal
  target: ?secret
  permissions:
  - s3:GetObject
  conditions:
  - iam_permission
  - resource_policy
  state_logic: 'inherit_weakest(CanReadData, ContainsSecret): if either contributor is CONDITIONAL or
    BLOCKED, inherit that state. ACTIVE only when both CanReadData and ContainsSecret are ACTIVE. The
    edge carries the same key_permission gate as the CanReadData input if the bucket uses SSE-KMS.'
  confidence: min(contributing_confidences) * 0.95
  derived_from:
  - ?principal CanReadData ?bucket (s3:GetObject)
  - ?bucket ContainsSecret ?secret (heuristic or Macie findings)
  false_positive_note: "Only emit when ContainsSecret is explicitly evidenced (heuristic patterns or Macie\
    \ findings), not inferred. The CanReadData input may be CONDITIONAL (key_permission) if the bucket\
    \ is SSE-KMS encrypted \u2014 inherit that gate; the secret read is then CONDITIONAL(key_permission)\
    \ until decrypt-gates-secret-read upgrades it. This bridge rule feeds credential-chains:read-secret-yields-identity."
  narrative: '{principal.name} can read {bucket.name} (s3:GetObject) and the bucket contains secrets ({secret.name});
    reading the bucket yields the secret material.'
move · open · esc close