Detection rules › Panther
GCP KMS Key Version Disabled or Destroyed
Detects when a KMS key version is disabled, scheduled for destruction, or destroyed. Disabling or destroying KMS key versions can be used to deny access to encrypted data—a ransomware tactic where attackers disable keys to prevent victims from accessing their data.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth | T1562 Impair Defenses |
| Impact | T1486 Data Encrypted for Impact |
Rules detecting the same action
Other rules on this platform that filter on the same API call or operation.
Rule body yaml
AnalysisType: rule
Filename: gcp_kms_erase_key.py
RuleID: "GCP.KMS.EraseKey"
DisplayName: "GCP KMS Key Version Disabled or Destroyed"
Enabled: true
Status: Experimental
LogTypes:
- GCP.AuditLog
Tags:
- GCP
- Google Cloud KMS
- Defense Evasion:Impair Defenses
- Impact:Data Encrypted for Impact
- Ransomware
Reports:
MITRE ATT&CK:
- TA0005:T1562
- TA0040:T1486
Severity: Info
Description: >
Detects when a KMS key version is disabled, scheduled for destruction, or destroyed.
Disabling or destroying KMS key versions can be used to deny access to encrypted data—a
ransomware tactic where attackers disable keys to prevent victims from accessing their data.
Runbook: |
1. Query GCP Audit logs for all KMS key operations by the principal email in the 24 hours before and after this alert
2. Check if the source IP is associated with known cloud provider IP ranges, VPN endpoints, or matches the user's typical access patterns
3. Search for other KMS key state changes (disabled, destroyed) across different keys in the same project in the past 6 hours
4. Identify which GCS buckets or other resources use this KMS key for encryption and assess data access impact
5. Look for other alerts related to ransomware indicators (e.g., bulk operations, unusual encryption activity) from this project in the past 7 days
Reference: https://cloud.google.com/kms/docs/key-states
SummaryAttributes:
- severity
- p_any_ip_addresses
- p_any_emails
Tests:
- Name: KMS Key Version Disabled
ExpectedResult: true
Log:
{
"protoPayload":
{
"at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo":
{
"oauthInfo":
{
"oauthClientId": "111111111111-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com",
},
"principalEmail": "denethor@lotr.com",
"principalSubject": "user:denethor@lotr.com",
},
"authorizationInfo":
[
{
"granted": true,
"permission": "cloudkms.cryptoKeyVersions.update",
"permissionType": "ADMIN_WRITE",
"resource": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"resourceAttributes":
{
"name": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"service": "google.cloud.kms",
"type": "cloudkms.googleapis.com/CryptoKeyVersion",
},
},
],
"metadata": {},
"methodName": "UpdateCryptoKeyVersion",
"request":
{
"@type": "type.googleapis.com/google.cloud.kms.v1.UpdateCryptoKeyVersionRequest",
"at_sign_type": "type.googleapis.com/google.cloud.kms.v1.UpdateCryptoKeyVersionRequest",
"cryptoKeyVersion":
{
"name": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"state": "DISABLED",
},
"updateMask": "state",
},
"requestMetadata":
{
"callerIP": "1.2.3.4",
"callerIp": "1.2.3.4",
"callerSuppliedUserAgent": "google-cloud-sdk gcloud/548.0.0 command/gcloud.kms.keys.versions.disable",
"destinationAttributes": {},
"requestAttributes":
{ "auth": {}, "time": "2025-12-15T15:40:47.296683147Z" },
},
"resourceLocation": { "currentLocations": ["us"] },
"resourceName": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"serviceName": "cloudkms.googleapis.com",
"status": {},
},
"insertId": "abc123def456",
"logName": "projects/test-project/logs/cloudaudit.googleapis.com%2Factivity",
"receiveTimestamp": "2025-12-15 15:40:48.642133512",
"resource":
{
"labels":
{
"crypto_key_id": "test-key",
"crypto_key_version_id": "1",
"key_ring_id": "test-keyring",
"location": "us",
"project_id": "test-project",
},
"type": "cloudkms_cryptokeyversion",
},
"severity": "NOTICE",
"timestamp": "2025-12-15 15:40:47.284488263",
}
- Name: KMS Key Version Enabled
ExpectedResult: false
Log:
{
"protoPayload":
{
"at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo":
{ "principalEmail": "denethor@lotr.com" },
"methodName": "UpdateCryptoKeyVersion",
"request":
{
"@type": "type.googleapis.com/google.cloud.kms.v1.UpdateCryptoKeyVersionRequest",
"cryptoKeyVersion":
{
"name": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"state": "ENABLED",
},
"updateMask": "state",
},
"resourceName": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"serviceName": "cloudkms.googleapis.com",
"status": {},
},
"resource":
{
"labels": { "project_id": "test-project" },
"type": "cloudkms_cryptokeyversion",
},
"timestamp": "2025-12-15 15:40:47.284488263",
}
- Name: KMS Key Version Destroyed
ExpectedResult: true
Log:
{
"protoPayload":
{
"at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo":
{ "principalEmail": "user@example.com" },
"methodName": "DestroyCryptoKeyVersion",
"request":
{
"@type": "type.googleapis.com/google.cloud.kms.v1.UpdateCryptoKeyVersionRequest",
"cryptoKeyVersion":
{
"name": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
},
},
"resourceName": "projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/cryptoKeyVersions/1",
"serviceName": "cloudkms.googleapis.com",
"status": {},
},
"resource":
{
"labels": { "project_id": "test-project" },
"type": "cloudkms_cryptokeyversion",
},
"timestamp": "2025-12-15 15:40:47.284488263",
}
Detection logic
Condition
protoPayload.serviceName eq "cloudkms.googleapis.com"
protoPayload.methodName eq "DestroyCryptoKeyVersion" or (protoPayload.methodName eq "UpdateCryptoKeyVersion" and protoPayload.request.updateMask eq "state" and protoPayload.request.cryptoKeyVersion.state in ["DISABLED", "DESTROY_SCHEDULED", "DESTROYED"])
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
protoPayload.methodName | eq |
|
protoPayload.request.cryptoKeyVersion.state | in |
|
protoPayload.request.updateMask | eq |
|
protoPayload.serviceName | eq |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
actor | protoPayload.authenticationInfo.principalEmail |
kms_key_version | protoPayload.resourceName |
new_state | protoPayload.request.cryptoKeyVersion.state |
source_ip | protoPayload.requestMetadata.callerIp |
project | resource.labels.project_id |
key_ring | resource.labels.key_ring_id |
crypto_key | resource.labels.crypto_key_id |
name | protoPayload.request.cryptoKeyVersion.name |