aws-timestream-read-data-contains-secret
Reading data from a Timestream table that contains secret material yields the ability to read those secrets, enabling credential-chain pivots.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?table) == Data
?table.provider_type == 'AWS::Timestream::Table'
node_type(?secret) ==
Secret
emit
| source type | Identity |
|---|---|
| target type | Secret |
| source | ?principal |
| target | ?secret |
| conditions | iam_permission key_permission |
| state logic | INHERIT_WEAKEST(CanReadData, ContainsSecret): if CanReadData is CONDITIONAL(key_permission) (table encrypted with CMK, decrypt not yet confirmed) then CONDITIONAL(key_permission); if CanReadData is BLOCKED then BLOCKED; else ACTIVE. ContainsSecret is a zero-cost structural link and never downgrades on its own. |
Narrative
{principal.name} can read data from {table.name} ({perm:CanReadData}), and {table.name} contains {secret.name} (secret material ingested as measures or dimensions); {principal.name} can therefore read {secret.name}.
Raw rule rules/derived/aws/timestream.yaml
id: aws-timestream-read-data-contains-secret
emits: CanReadSecret
description: Reading data from a Timestream table that contains secret material yields the ability to
read those secrets, enabling credential-chain pivots.
match:
- - principal: null
- CanReadData
- table: null
- - table: null
- ContainsSecret
- secret: null
where:
- node_type(?table) == Data
- ?table.provider_type == 'AWS::Timestream::Table'
- node_type(?secret) == Secret
emit:
source_type: Identity
target_type: Secret
source: ?principal
target: ?secret
permissions: []
conditions:
- iam_permission
- key_permission
state_logic: 'INHERIT_WEAKEST(CanReadData, ContainsSecret): if CanReadData is CONDITIONAL(key_permission)
(table encrypted with CMK, decrypt not yet confirmed) then CONDITIONAL(key_permission); if CanReadData
is BLOCKED then BLOCKED; else ACTIVE. ContainsSecret is a zero-cost structural link and never downgrades
on its own.'
confidence: min(contributing_confidences) * 0.95
derived_from:
- ?principal CanReadData ?table
- ?table ContainsSecret ?secret
false_positive_note: 'Only emit when the ContainsSecret link is explicitly evidenced (analyst or automated
scan asserted that the table''s data includes credential material); do not emit speculatively. Inherit
the key_permission gate from CanReadData: if the table is CMK-encrypted and CanReadData is CONDITIONAL(key_permission),
so is CanReadSecret; cite credential-chains:decrypt-gates-secret-read to upgrade when the decrypt
is confirmed.'
narrative: '{principal.name} can read data from {table.name} ({perm:CanReadData}), and {table.name}
contains {secret.name} (secret material ingested as measures or dimensions); {principal.name} can
therefore read {secret.name}.'