aws-kms-decrypt-unlocks-data
Decrypt on the CMK protecting a store completes the key_permission gate for data reads.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanDecrypt {'key': None}
{'store': None} ContainsResourceReference {'key': None}
where
node_class(?store) in [Storage, Data]
structural 'encrypted-by' link: the store references its encrypting CMK via
ContainsResourceReference (source [Data, Storage, Compute] — ?store conforms), per providers/aws/kms.md §13; NOT LocatedIn, whose target set is [AdministrativeBoundary, Network]
?store is SSE-KMS/encrypted with ?key (S3 bucket default KMS key, EBS volume, RDS/Aurora, DynamoDB)
?principal also holds the data-plane read action on ?store (e.g. s3:GetObject) and any network reachability
emit
| source | ?principal |
|---|---|
| target | ?store |
| permissions | kms:Decrypt s3:GetObject |
| conditions | iam_permission resource_policy network_reachability key_permission condition_expression |
| state logic | if ?principal has the store-read action AND kms:Decrypt AND reachability: ACTIVE; if only kms:Decrypt confirmed: CONDITIONAL(iam_permission); inherit CONDITIONAL from a gated CanDecrypt input |
Narrative
{principal.name} can decrypt with {key.name}, satisfying the KMS gate on {store.name}; with the data-plane read action it reads the encrypted data.
Raw rule rules/derived/aws/kms.yaml
id: aws-kms-decrypt-unlocks-data
emits: CanReadData
description: Decrypt on the CMK protecting a store completes the key_permission gate for data reads.
match:
- - principal: null
- CanDecrypt
- key: null
- - store: null
- ContainsResourceReference
- key: null
where:
- node_class(?store) in [Storage, Data]
- "structural 'encrypted-by' link: the store references its encrypting CMK via ContainsResourceReference\
\ (source [Data, Storage, Compute] \u2014 ?store conforms), per providers/aws/kms.md \xA713; NOT LocatedIn,\
\ whose target set is [AdministrativeBoundary, Network]"
- ?store is SSE-KMS/encrypted with ?key (S3 bucket default KMS key, EBS volume, RDS/Aurora, DynamoDB)
- ?principal also holds the data-plane read action on ?store (e.g. s3:GetObject) and any network reachability
emit:
source: ?principal
target: ?store
permissions:
- kms:Decrypt
- s3:GetObject
conditions:
- iam_permission
- resource_policy
- network_reachability
- key_permission
- condition_expression
state_logic: 'if ?principal has the store-read action AND kms:Decrypt AND reachability: ACTIVE; if only
kms:Decrypt confirmed: CONDITIONAL(iam_permission); inherit CONDITIONAL from a gated CanDecrypt input'
confidence: min(contributing_confidences) * 0.9
derived_from:
- <CanDecrypt edge_id>
- <ContainsResourceReference store->key edge_id>
false_positive_note: "kms:Decrypt is necessary but not sufficient \u2014 the store's own data-plane\
\ read (s3:GetObject / etc.), resource policy, and network reachability still apply. For S3 SSE-KMS\
\ the object read needs both s3:GetObject AND kms:Decrypt on the bucket key; honor kms:ViaService==s3.amazonaws.com\
\ scoping. This rule only supplies the key_permission half."
narrative: '{principal.name} can decrypt with {key.name}, satisfying the KMS gate on {store.name}; with
the data-plane read action it reads the encrypted data.'