gcp-kms-can-decapsulate
cloudkms.cryptoKeyVersions.useToDecapsulate lets a principal decapsulate a shared secret with a KEM key.
match (effective permission)
{
"action": "cloudkms.cryptoKeyVersions.useToDecapsulate",
"resource_type": "google.cloud.kms.CryptoKey"
}
where
CryptoKey.purpose is a KEM (key-encapsulation) purpose — the Decapsulate
API recovers the shared secret from a ciphertext encapsulation (RAW/PQC KEM)
the effective action is cloudkms.cryptoKeyVersions.useToDecapsulate specifically — useToDecrypt does NOT apply to a KEM key and is NOT accepted here
at least one CryptoKeyVersion is ENABLED
emit
| target type | EncryptionKey |
|---|---|
| source | <principal> |
| target | <CryptoKey (EncryptionKey subtype, KEM)> |
| permissions | cloudkms.cryptoKeyVersions.useToDecapsulate |
| conditions | iam_permission resource_policy key_permission service_state |
| state logic | ACTIVE if useToDecapsulate resolves on a KEM key AND >=1 version ENABLED; CONDITIONAL(service_state) if all versions DISABLED (re-enableable by a cryptoKeyVersions.update holder); BLOCKED if all versions DESTROYED, or a VPC-SC perimeter / IAM deny policy denies cloudkms.cryptoKeyVersions.useToDecapsulate at the effective scope (denied_by=<perimeter/deny>). |
Narrative
{principal.name} can decapsulate the shared secret of KEM key {key.name} (cloudkms.cryptoKeyVersions.useToDecapsulate) - recovering the wrapped secret.
Raw rule rules/derived/gcp/kms.yaml
id: gcp-kms-can-decapsulate
emits: CanDecrypt
description: cloudkms.cryptoKeyVersions.useToDecapsulate lets a principal decapsulate a shared secret
with a KEM key.
match_effective_permission:
action: cloudkms.cryptoKeyVersions.useToDecapsulate
resource_type: google.cloud.kms.CryptoKey
where:
- "CryptoKey.purpose is a KEM (key-encapsulation) purpose \u2014 the Decapsulate API recovers the shared\
\ secret from a ciphertext encapsulation (RAW/PQC KEM)"
- "the effective action is cloudkms.cryptoKeyVersions.useToDecapsulate specifically \u2014 useToDecrypt\
\ does NOT apply to a KEM key and is NOT accepted here"
- at least one CryptoKeyVersion is ENABLED
emit:
target_type: EncryptionKey
source: <principal>
target: <CryptoKey (EncryptionKey subtype, KEM)>
permissions:
- cloudkms.cryptoKeyVersions.useToDecapsulate
conditions:
- iam_permission
- resource_policy
- key_permission
- service_state
state_logic: ACTIVE if useToDecapsulate resolves on a KEM key AND >=1 version ENABLED; CONDITIONAL(service_state)
if all versions DISABLED (re-enableable by a cryptoKeyVersions.update holder); BLOCKED if all versions
DESTROYED, or a VPC-SC perimeter / IAM deny policy denies cloudkms.cryptoKeyVersions.useToDecapsulate
at the effective scope (denied_by=<perimeter/deny>).
confidence: min(contributing_confidences) * 0.97
derived_from:
- <effective cloudkms.cryptoKeyVersions.useToDecapsulate grant>
false_positive_note: "useToDecapsulate is a DISTINCT permission from useToDecrypt and applies ONLY to\
\ KEM-purpose keys. A useToDecrypt grant does NOT confer decapsulation and a useToDecapsulate grant\
\ does NOT confer decrypt \u2014 do not cross-map them. Emit only when the effective action is useToDecapsulate\
\ on a KEM key with >=1 ENABLED version. Recovering a KEM shared secret is a decrypt-equivalent capability\
\ (models as CanDecrypt) but keep the permission name exact."
narrative: "{principal.name} can decapsulate the shared secret of KEM key {key.name} (cloudkms.cryptoKeyVersions.useToDecapsulate)\
\ \u2014 recovering the wrapped secret."