Detection rules › YARA-L
Unauthorized KMS Decryption
Detects when a Key Management Service (KMS) decryption operation is carried out by a service account that's not in the allowlist. This behavior may indicate unauthorized access to information.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | No specific technique |
Event coverage
| Provider | Event |
|---|---|
| GCP-cloudkms.googleapis.com | Decrypt |
Rule body yaral
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
rule gcp_kms_decryption_by_unexpected_service_account {
meta:
author = "Drew Pilarski - Tempus AI"
description = "Detects when a Key Management Service (KMS) decryption operation is carried out by a service account that's not in the allowlist. This behavior may indicate unauthorized access to information."
rule_id = "mr_90cd5b0d-60a7-4028-bc41-dce0947fbafd"
rule_name = "Unauthorized KMS Decryption"
reference = "Internal Security Policy" // Include link to your organization's internal documentation if available
mitre_attack_tactic = "Persistence"
mitre_attack_technique = "Valid Accounts: Cloud Accounts"
type = "Alert"
platform = "GCP"
data_source = "Cloud Audit Logs"
severity = "Medium" // Adjust based on your risk assessment
priority = "Medium" // Adjust based on your incident response process
events:
$decrypt.metadata.product_name = "Google Cloud Platform"
$decrypt.metadata.vendor_name = "Google Cloud Platform"
// Generic KMS Key Pattern - Pick the relevant one to your environment
re.regex($decrypt.target.resource.name, `^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$`)
$decrypt.metadata.product_event_type = "Decrypt"
not $decrypt.principal.user.email_addresses in %kms_decryption_service_account_allowlist
outcome:
$action = $decrypt.metadata.product_event_type
$account_name = array_distinct($decrypt.principal.user.email_addresses)
$mitre_attack_tactic = array_distinct("Persistence")
$mitre_attack_technique = array_distinct("Valid Accounts: Cloud Accounts")
$mitre_attack_technique_id = array_distinct("T1078.004")
condition:
$decrypt
}
Detection logic
Fires when at least one $decrypt event.
Events
$decrypt
target.resource.name matches "^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$"metadata.product_event_type = "Decrypt"principal.user.email_addresses in "%kms_decryption_service_account_allowlist"
Outcome
Fields the detection emits on a match. $risk_score drives alerting; Chronicle surfaces the rest on the detection.
| Field | Expression |
|---|---|
action | $decrypt.metadata.product_event_type |
account_name | array_distinct($decrypt.principal.user.email_addresses) |