aws-s3-read-data-sse-kms

s3:GetObject on a SSE-KMS bucket: read is CONDITIONAL on kms:Decrypt for the wrapping CMK. Cite credential-chains:decrypt-gates-secret-read to upgrade to ACTIVE.

derived aws emits CanReadData

match

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

{'principal': None} HasPermission {'bucket': None}

where

node_type(?bucket) == ObjectStorage ?bucket.provider_type == 'AWS::S3::Bucket' ?principal has EFFECTIVE s3:GetObject on ?bucket ARN ?bucket.properties.ServerSideEncryptionRule.KMSMasterKeyID is not null (SSE-KMS with CMK)

emit

source typeIdentity
target typeObjectStorage
source?principal
target?bucket
permissionss3:GetObject kms:Decrypt
conditionsiam_permission resource_policy key_permission
state logicCONDITIONAL(key_permission): the caller holds s3:GetObject (IAM + bucket policy confirmed) but kms:Decrypt on the wrapping CMK is NOT yet confirmed. The edge is BLOCKED when the KMS key policy or an SCP explicitly denies kms:Decrypt to this principal. Upgrade to ACTIVE via credential-chains:decrypt-gates-secret-read when the same principal also holds CanDecrypt on the specific CMK referenced in ?bucket.properties.KMSMasterKeyID. The kms:ViaService condition on the key policy (kms:ViaService: s3.*.amazonaws.com) is automatically satisfied by S3-mediated decryption; do not treat it as a block.

Narrative

{principal.name} has s3:GetObject on {bucket.name} (SSE-KMS encrypted with CMK {bucket.kmsKeyId}), but decryption is gated on kms:Decrypt for that CMK. The read capability is CONDITIONAL(key_permission) until credential-chains:decrypt-gates-secret-read confirms decrypt access.

Raw rule rules/derived/aws/s3.yaml

id: aws-s3-read-data-sse-kms
emits: CanReadData
description: 's3:GetObject on a SSE-KMS bucket: read is CONDITIONAL on kms:Decrypt for the wrapping CMK.
  Cite credential-chains:decrypt-gates-secret-read to upgrade to ACTIVE.'
match:
- - principal: null
  - HasPermission
  - bucket: null
where:
- node_type(?bucket) == ObjectStorage
- ?bucket.provider_type == 'AWS::S3::Bucket'
- ?principal has EFFECTIVE s3:GetObject on ?bucket ARN
- ?bucket.properties.ServerSideEncryptionRule.KMSMasterKeyID is not null (SSE-KMS with CMK)
emit:
  source_type: Identity
  target_type: ObjectStorage
  source: ?principal
  target: ?bucket
  permissions:
  - s3:GetObject
  - kms:Decrypt
  conditions:
  - iam_permission
  - resource_policy
  - key_permission
  state_logic: 'CONDITIONAL(key_permission): the caller holds s3:GetObject (IAM + bucket policy confirmed)
    but kms:Decrypt on the wrapping CMK is NOT yet confirmed. The edge is BLOCKED when the KMS key policy
    or an SCP explicitly denies kms:Decrypt to this principal. Upgrade to ACTIVE via credential-chains:decrypt-gates-secret-read
    when the same principal also holds CanDecrypt on the specific CMK referenced in ?bucket.properties.KMSMasterKeyID.
    The kms:ViaService condition on the key policy (kms:ViaService: s3.*.amazonaws.com) is automatically
    satisfied by S3-mediated decryption; do not treat it as a block.'
  confidence: min(contributing_confidences) * 0.90
  derived_from:
  - ?principal HasPermission ?bucket (s3:GetObject effective permission)
  - ?bucket properties.ServerSideEncryptionRule.KMSMasterKeyID (SSE-KMS CMK)
  - "credential-chains:decrypt-gates-secret-read (upgrade to ACTIVE \u2014 cited not re-derived)"
  false_positive_note: "Do NOT emit this as ACTIVE \u2014 always CONDITIONAL(key_permission) when the\
    \ bucket uses a CMK and the caller's kms:Decrypt is unconfirmed. SSE-S3 (aws:s3) and service-managed\
    \ KMS keys are transparent \u2014 use rule aws-s3-read-data-get-object (ACTIVE) for those. DSSE-KMS\
    \ (dual-layer SSE) requires TWO distinct CMK decryptions; apply the same gate. A CMK in a different\
    \ account (cross-account KMS key) additionally requires the key policy in that account to grant kms:Decrypt\
    \ to this principal \u2014 honor it. The kms:ViaService condition (kms:ViaService: s3.*.amazonaws.com)\
    \ does NOT require the caller to explicitly include a ViaService context \u2014 S3 sets it automatically.\
    \ Do NOT treat it as an additional caller requirement."
  narrative: '{principal.name} has s3:GetObject on {bucket.name} (SSE-KMS encrypted with CMK {bucket.kmsKeyId}),
    but decryption is gated on kms:Decrypt for that CMK. The read capability is CONDITIONAL(key_permission)
    until credential-chains:decrypt-gates-secret-read confirms decrypt access.'
move · open · esc close