aws-kms-cross-account-key-use
An external principal permitted by the key policy/grant can use the key cross-account.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'key': None}
HasPolicy {'keypolicy': None}
{'keypolicy': None} CrossAccountTrust {'external': None}
where
node_type(?key) ==
EncryptionKey (CanDecrypt target must be an EncryptionKey; HasPolicy binds the key to its key-policy ResourcePolicy node)
node_class(?external) == Identity (CanDecrypt source is [Identity, Compute]; an ExternalIdentity is an Identity subtype and conforms. A CrossAccountTrust whose target is an Account node is NOT a valid CanDecrypt source — this guard suppresses those)
the cross-account key-policy statement or grant permits kms:Decrypt (or Sign/GenerateDataKey) for ?external
?external.account != ?key.account
emit
| target type | EncryptionKey |
|---|---|
| source | ?external |
| target | ?key |
| permissions | kms:Decrypt |
| conditions | resource_policy condition_expression |
| state logic | if the key policy/grant grants the crypto op to ?external with no unmet condition: ACTIVE; if kms:ViaService/EncryptionContext/aws:SourceArn narrows it: CONDITIONAL(condition_expression) |
Narrative
{external.name} (account {external.account}) is permitted by {key.name}'s key policy/grant to decrypt with it across accounts.
Raw rule rules/derived/aws/kms.yaml
id: aws-kms-cross-account-key-use
emits: CanDecrypt
description: An external principal permitted by the key policy/grant can use the key cross-account.
match:
- - key: null
- HasPolicy
- keypolicy: null
- - keypolicy: null
- CrossAccountTrust
- external: null
where:
- node_type(?key) == EncryptionKey (CanDecrypt target must be an EncryptionKey; HasPolicy binds the key
to its key-policy ResourcePolicy node)
- "node_class(?external) == Identity (CanDecrypt source is [Identity, Compute]; an ExternalIdentity is\
\ an Identity subtype and conforms. A CrossAccountTrust whose target is an Account node is NOT a valid\
\ CanDecrypt source \u2014 this guard suppresses those)"
- the cross-account key-policy statement or grant permits kms:Decrypt (or Sign/GenerateDataKey) for ?external
- ?external.account != ?key.account
emit:
target_type: EncryptionKey
source: ?external
target: ?key
permissions:
- kms:Decrypt
conditions:
- resource_policy
- condition_expression
state_logic: 'if the key policy/grant grants the crypto op to ?external with no unmet condition: ACTIVE;
if kms:ViaService/EncryptionContext/aws:SourceArn narrows it: CONDITIONAL(condition_expression)'
confidence: min(contributing_confidences) * 0.9
derived_from:
- <HasPolicy key->keypolicy edge_id>
- <CrossAccountTrust edge_id>
false_positive_note: "Cross-account KMS is key USE, not account entry. SourceArn/SourceAccount and kms:ViaService\
\ scoping on the key-policy statement narrow WHO and HOW \u2014 honor them. A cross-account statement\
\ granting only kms:DescribeKey is recon, not CanDecrypt."
narrative: '{external.name} (account {external.account}) is permitted by {key.name}''s key policy/grant
to decrypt with it across accounts.'