aws-kms-cross-account-key-use

An external principal permitted by the key policy/grant can use the key cross-account.

derived aws emits CanDecrypt

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 typeEncryptionKey
source?external
target?key
permissionskms:Decrypt
conditionsresource_policy condition_expression
state logicif 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.'
move · open · esc close