Back
Idb7da45ce-fcc8-43c7-a37c-c08454579d26
RulenameGCP Audit Logs - Data Access Logging Exemption Added for Principal
DescriptionDetects when a principal (user or service account) is exempted from GCP data access audit logging.

This is a critical security event as it reduces visibility into privileged operations and may indicate an attempt to hide malicious activity.

Adversaries may exempt their accounts from audit logging to evade detection while performing reconnaissance, privilege escalation, or data exfiltration.

This rule monitors SetIamPolicy operations that add audit log exemptions for ADMIN_READ, DATA_READ, or DATA_WRITE log types.
SeverityHigh
TacticsDefenseEvasion
PrivilegeEscalation
TechniquesT1562.008
T1078.004
Required data connectorsGCPAuditLogsDefinition
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPDataAccessLoggingExemption.yaml
Version1.0.0
Arm templateb7da45ce-fcc8-43c7-a37c-c08454579d26.json
Deploy To Azure
GCPAuditLogs
 | where ServiceName == "cloudresourcemanager.googleapis.com"
 | where MethodName == "SetIamPolicy"
 | where GCPResourceType == "project" and Severity == "NOTICE"
 | where isnotempty(ServiceData)
 | extend ServiceDataJson = parse_json(ServiceData)
 | extend PolicyDelta = ServiceDataJson.policyDelta.auditConfigDeltas
 | where isnotempty(PolicyDelta)
 | mv-expand ConfigDelta = PolicyDelta
 | where ConfigDelta.action == "ADD"
 | extend LogType = tostring(ConfigDelta.logType)
 | where LogType in ("ADMIN_READ", "DATA_READ", "DATA_WRITE")
 | extend 
     ExemptedMember = tostring(ConfigDelta.exemptedMember),
     ServiceAffected = tostring(ConfigDelta.service),
     RequestMetadataJson = parse_json(RequestMetadata),
     AuthInfoJson = parse_json(AuthenticationInfo)
 | where isnotempty(ExemptedMember)
 | extend 
     CallerIpAddress = tostring(RequestMetadataJson.callerIp),
     UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),
     AuthEmail = tostring(AuthInfoJson.principalEmail),
     ExemptedAccountName = tostring(split(ExemptedMember, ":")[1])
 | summarize 
     ExemptedLogTypes = make_set(LogType, 10),
     ExemptedServices = make_set(ServiceAffected, 50),
     FirstExemption = min(TimeGenerated),
     LastExemption = max(TimeGenerated)
     by PrincipalEmail, ProjectId, GCPResourceName, ExemptedMember, 
        CallerIpAddress, UserAgent, LogName, ExemptedAccountName, MethodName, ServiceName, AuthEmail
 | extend
     AccountName = tostring(split(PrincipalEmail, "@")[0]), 
     AccountUPNSuffix = tostring(split(PrincipalEmail, "@")[1])
 | project TimeGenerated = LastExemption,
     PrincipalEmail,
     ProjectId,
     ResourceName = GCPResourceName,
     ExemptedMember,
     ExemptedAccountName,
     ExemptedLogTypes,
     ExemptedServices,
     FirstExemption,
     LastExemption,
     CallerIpAddress,
     UserAgent,
     AuthEmail,
     MethodName,
     ServiceName,
     LogName,
     AccountName,
     AccountUPNSuffix
tactics:
- DefenseEvasion
- PrivilegeEscalation
requiredDataConnectors:
- dataTypes:
  - GCPAuditLogs
  connectorId: GCPAuditLogsDefinition
tags:
- Cloud Security
- Audit Logging
- Defense Evasion
queryPeriod: 1h
kind: Scheduled
severity: High
customDetails:
  ProjectId: ProjectId
  ExemptedAccountName: ExemptedAccountName
  ExemptedServices: ExemptedServices
  UserAgent: UserAgent
  ExemptedMember: ExemptedMember
  ExemptedLogTypes: ExemptedLogTypes
queryFrequency: 1h
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPDataAccessLoggingExemption.yaml
triggerThreshold: 0
description: |
  'Detects when a principal (user or service account) is exempted from GCP data access audit logging.
  This is a critical security event as it reduces visibility into privileged operations and may indicate an attempt to hide malicious activity.
  Adversaries may exempt their accounts from audit logging to evade detection while performing reconnaissance, privilege escalation, or data exfiltration.
  This rule monitors SetIamPolicy operations that add audit log exemptions for ADMIN_READ, DATA_READ, or DATA_WRITE log types.'
id: b7da45ce-fcc8-43c7-a37c-c08454579d26
triggerOperator: gt
alertDetailsOverride:
  alertDescriptionFormat: |-
    Principal {{ExemptedAccountName}} added as exception from Data Access logging in project {{ProjectId}} for Service {{ExemptedServices}}.
    This action reduces audit visibility and may indicate an attempt to evade detection. Verify this change was authorized and investigate any suspicious activity performed by the exempted principal.
  alertDisplayNameFormat: GCP Data Access Logging Exemption Added for {{ExemptedAccountName}} by {{PrincipalEmail}} in Service {{ExemptedServices}}
status: Available
relevantTechniques:
- T1562.008
- T1078.004
version: 1.0.0
name: GCP Audit Logs - Data Access Logging Exemption Added for Principal
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: PrincipalEmail
    identifier: FullName
  - columnName: AccountName
    identifier: Name
  - columnName: AccountUPNSuffix
    identifier: UPNSuffix
- entityType: IP
  fieldMappings:
  - columnName: CallerIpAddress
    identifier: Address
- entityType: CloudApplication
  fieldMappings:
  - columnName: ProjectId
    identifier: Name
  - columnName: ResourceName
    identifier: InstanceName
query: |
  GCPAuditLogs
   | where ServiceName == "cloudresourcemanager.googleapis.com"
   | where MethodName == "SetIamPolicy"
   | where GCPResourceType == "project" and Severity == "NOTICE"
   | where isnotempty(ServiceData)
   | extend ServiceDataJson = parse_json(ServiceData)
   | extend PolicyDelta = ServiceDataJson.policyDelta.auditConfigDeltas
   | where isnotempty(PolicyDelta)
   | mv-expand ConfigDelta = PolicyDelta
   | where ConfigDelta.action == "ADD"
   | extend LogType = tostring(ConfigDelta.logType)
   | where LogType in ("ADMIN_READ", "DATA_READ", "DATA_WRITE")
   | extend 
       ExemptedMember = tostring(ConfigDelta.exemptedMember),
       ServiceAffected = tostring(ConfigDelta.service),
       RequestMetadataJson = parse_json(RequestMetadata),
       AuthInfoJson = parse_json(AuthenticationInfo)
   | where isnotempty(ExemptedMember)
   | extend 
       CallerIpAddress = tostring(RequestMetadataJson.callerIp),
       UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),
       AuthEmail = tostring(AuthInfoJson.principalEmail),
       ExemptedAccountName = tostring(split(ExemptedMember, ":")[1])
   | summarize 
       ExemptedLogTypes = make_set(LogType, 10),
       ExemptedServices = make_set(ServiceAffected, 50),
       FirstExemption = min(TimeGenerated),
       LastExemption = max(TimeGenerated)
       by PrincipalEmail, ProjectId, GCPResourceName, ExemptedMember, 
          CallerIpAddress, UserAgent, LogName, ExemptedAccountName, MethodName, ServiceName, AuthEmail
   | extend
       AccountName = tostring(split(PrincipalEmail, "@")[0]), 
       AccountUPNSuffix = tostring(split(PrincipalEmail, "@")[1])
   | project TimeGenerated = LastExemption,
       PrincipalEmail,
       ProjectId,
       ResourceName = GCPResourceName,
       ExemptedMember,
       ExemptedAccountName,
       ExemptedLogTypes,
       ExemptedServices,
       FirstExemption,
       LastExemption,
       CallerIpAddress,
       UserAgent,
       AuthEmail,
       MethodName,
       ServiceName,
       LogName,
       AccountName,
       AccountUPNSuffix
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/b7da45ce-fcc8-43c7-a37c-c08454579d26')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/b7da45ce-fcc8-43c7-a37c-c08454579d26')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "Principal {{ExemptedAccountName}} added as exception from Data Access logging in project {{ProjectId}} for Service {{ExemptedServices}}.\nThis action reduces audit visibility and may indicate an attempt to evade detection. Verify this change was authorized and investigate any suspicious activity performed by the exempted principal.",
          "alertDisplayNameFormat": "GCP Data Access Logging Exemption Added for {{ExemptedAccountName}} by {{PrincipalEmail}} in Service {{ExemptedServices}}"
        },
        "alertRuleTemplateName": "b7da45ce-fcc8-43c7-a37c-c08454579d26",
        "customDetails": {
          "ExemptedAccountName": "ExemptedAccountName",
          "ExemptedLogTypes": "ExemptedLogTypes",
          "ExemptedMember": "ExemptedMember",
          "ExemptedServices": "ExemptedServices",
          "ProjectId": "ProjectId",
          "UserAgent": "UserAgent"
        },
        "description": "'Detects when a principal (user or service account) is exempted from GCP data access audit logging.\nThis is a critical security event as it reduces visibility into privileged operations and may indicate an attempt to hide malicious activity.\nAdversaries may exempt their accounts from audit logging to evade detection while performing reconnaissance, privilege escalation, or data exfiltration.\nThis rule monitors SetIamPolicy operations that add audit log exemptions for ADMIN_READ, DATA_READ, or DATA_WRITE log types.'\n",
        "displayName": "GCP Audit Logs - Data Access Logging Exemption Added for Principal",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "PrincipalEmail",
                "identifier": "FullName"
              },
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "CallerIpAddress",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "ProjectId",
                "identifier": "Name"
              },
              {
                "columnName": "ResourceName",
                "identifier": "InstanceName"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Google%20Cloud%20Platform%20Audit%20Logs/Analytic%20Rules/GCPDataAccessLoggingExemption.yaml",
        "query": "GCPAuditLogs\n | where ServiceName == \"cloudresourcemanager.googleapis.com\"\n | where MethodName == \"SetIamPolicy\"\n | where GCPResourceType == \"project\" and Severity == \"NOTICE\"\n | where isnotempty(ServiceData)\n | extend ServiceDataJson = parse_json(ServiceData)\n | extend PolicyDelta = ServiceDataJson.policyDelta.auditConfigDeltas\n | where isnotempty(PolicyDelta)\n | mv-expand ConfigDelta = PolicyDelta\n | where ConfigDelta.action == \"ADD\"\n | extend LogType = tostring(ConfigDelta.logType)\n | where LogType in (\"ADMIN_READ\", \"DATA_READ\", \"DATA_WRITE\")\n | extend \n     ExemptedMember = tostring(ConfigDelta.exemptedMember),\n     ServiceAffected = tostring(ConfigDelta.service),\n     RequestMetadataJson = parse_json(RequestMetadata),\n     AuthInfoJson = parse_json(AuthenticationInfo)\n | where isnotempty(ExemptedMember)\n | extend \n     CallerIpAddress = tostring(RequestMetadataJson.callerIp),\n     UserAgent = tostring(RequestMetadataJson.callerSuppliedUserAgent),\n     AuthEmail = tostring(AuthInfoJson.principalEmail),\n     ExemptedAccountName = tostring(split(ExemptedMember, \":\")[1])\n | summarize \n     ExemptedLogTypes = make_set(LogType, 10),\n     ExemptedServices = make_set(ServiceAffected, 50),\n     FirstExemption = min(TimeGenerated),\n     LastExemption = max(TimeGenerated)\n     by PrincipalEmail, ProjectId, GCPResourceName, ExemptedMember, \n        CallerIpAddress, UserAgent, LogName, ExemptedAccountName, MethodName, ServiceName, AuthEmail\n | extend\n     AccountName = tostring(split(PrincipalEmail, \"@\")[0]), \n     AccountUPNSuffix = tostring(split(PrincipalEmail, \"@\")[1])\n | project TimeGenerated = LastExemption,\n     PrincipalEmail,\n     ProjectId,\n     ResourceName = GCPResourceName,\n     ExemptedMember,\n     ExemptedAccountName,\n     ExemptedLogTypes,\n     ExemptedServices,\n     FirstExemption,\n     LastExemption,\n     CallerIpAddress,\n     UserAgent,\n     AuthEmail,\n     MethodName,\n     ServiceName,\n     LogName,\n     AccountName,\n     AccountUPNSuffix\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [
          "T1562.008",
          "T1078.004"
        ],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "DefenseEvasion",
          "PrivilegeEscalation"
        ],
        "tags": [
          "Cloud Security",
          "Audit Logging",
          "Defense Evasion"
        ],
        "techniques": [
          "T1078",
          "T1562"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}