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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
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. |
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.'