Skip to main content

Audit Logs

Exam guide§3.4

Cloud Audit Logs

Cloud Audit Logs answer "who did what, where, and when." There are four types, and the single most tested fact is which ones are on by default.

Admin ActivityON by default
Config / write changes - create a VM, set IAM
Cannot be disabled. 400-day retention.
System EventON by default
Google-initiated actions - live migration
Free, automatic.
Policy DeniedON by default
Requests denied by a security policy - VPC SC, IAM
Free.
Data AccessOFF by default
Reads of data and metadata - read a GCS object, run a query
OFF by default (except BigQuery). Explicitly enable. Can be huge and costly.
The four Cloud Audit Log types. Three are always on and free; Data Access is the exception - off by default (except BigQuery), explicitly enabled, and potentially huge and costly.
DECISIONData Access is the whole question

"We need a record of who read customer data" = enable Data Access logs (they're off by default). "Track config changes / who created resources" = Admin Activity (already on). Never confuse read-tracking (Data Access) with change-tracking (Admin Activity).

Pick this when: auditing who READ data → Data Access logs (off by default); who CHANGED config → Admin Activity

Enabling Data Access logs

Enabled per-service in the project/folder/org IAM audit config, choosing ADMIN_READ, DATA_READ, and/or DATA_WRITE. Turning it on org-wide can generate an enormous, expensive volume - scope it deliberately.

CommandsView and set the audit config
gcloud projects get-iam-policy my-proj-id --format=json # see auditConfigs
# then edit the auditConfigs block and:
gcloud projects set-iam-policy my-proj-id policy.json
FactsThe three Data Access information types
  • Admin-read - reads of metadata/config (viewed a bucket's settings).
  • Data-read - reads of user data (listed and downloaded a Cloud Storage object).
  • Data-write - writes of user data (created a Cloud Storage object).

Data Access logs can be enabled at organization / folder / project / service level, and the effective config is the union - a child can't disable what a parent enabled. You can exempt specific principals to cut volume and cost.

Access Transparency

Access Transparency logs record actions taken by Google personnel when they access your content (e.g. a support engineer working a ticket) - as opposed to Cloud Audit Logs, which record actions by members of your organization. Enterprises with a qualifying support package can enable them and receive events in near-real time through the APIs, Cloud Logging, and Security Command Center.

Cloud Audit Logs
YOUR people
"Who on my team touched this?"
Actions by members of your own organization - the four audit log types.
Access Transparency
GOOGLE's people
"Did a Googler access my data, and why?"
Actions by Google personnel accessing your content (e.g. a support engineer on a ticket). Needs a qualifying support package; events arrive near-real-time via APIs, Cloud Logging, and Security Command Center.
Two logs, two different actors: Cloud Audit Logs record what YOUR people do; Access Transparency records what GOOGLE personnel do when they touch your content.
DECISIONAudit Logs = your people; Access Transparency = Google's people

"Who on my team touched this?" -> Cloud Audit Logs. "Did a Googler access my data, and why?" -> Access Transparency. They answer different questions; don't swap them.

Pick this when: someone on your team → Cloud Audit Logs; a Google employee → Access Transparency

Audit log entry format

Every audit log entry is a LogEntry. What makes it an audit entry is the protoPayload field, which holds an AuditLog object. Key fields: logName (tells you which of the four audit logs), protoPayload.principalEmail (who did it), serviceName + methodName (what), and resourceName (where). An operation field appears only for large or long-running entries.

A Data Access entry for a BigQuery query looks like this in the expanded object view - the logName (.../data_access) tells you which audit log, the protoPayload holds the AuditLog, and principalEmail is the "who":

{ insertId: "-77e5fge38tyo" logName: "projects/<projectID>/logs/cloudaudit.googleapis.com%2Fdata_access"which of the four audit logs operation: {only on large / long-running entries first: true id: "1581200795118:bquxjob_56996f5_17026e67aa2" producer: "bigquery.googleapis.com" } protoPayload: {the AuditLog - makes it an audit entry @type: "type.googleapis.com/google.cloud.audit.AuditLog" authenticationInfo: { principalEmail: "cloudysanfrancisco@gmail.com"principalEmail = WHO } authorizationInfo: [2] methodName: "jobservice.getqueryresults"methodName = WHAT requestMetadata: {…} resourceName: "projects/<project_ID>/queries/bquxjob_1eb1f384_17026e9d185"resourceName = WHERE serviceData: {…} serviceName: "bigquery.googleapis.com" status: {…} } receiveTimestamp: "2020-02-08T22:27:06.410866127Z" resource: { labels: { project_id: "<project_ID>", op_unit: "USA" } type: "bigquery_resource" } severity: "INFO" timestamp: "2020-02-08T22:27:05.908Z"}
One Data Access audit entry (a BigQuery query) with its key fields called out: logName says which of the four audit logs; protoPayload holds the AuditLog that makes it an audit entry; principalEmail / methodName / resourceName answer who / what / where. The operation field only appears on large or long-running entries.

Expand serviceData and you would see the query text itself - so when someone runs that unexpected $40,000 query, you can see who ran it and what it was. Google publishes a standard list of official serviceName values as a reference.

GotchaprotoPayload is the audit-log tell

A log entry with a protoPayload holding an AuditLog object is an audit entry; principalEmail is the "who". For a BigQuery entry the serviceData even shows the query text - so you can see who ran that surprise $40,000 query.

Best practices

Plan first  organization → folder → project  ·  prove it in a test project  ·  roll out
1Determine & set org-level Data Access
  • Data Access logs can be enabled as high as the organization
  • Org-wide = fullest trail, but grows large, bills per GB, adds QPS
  • Exempt noisy principals or scope to services to control cost
2Infrastructure as Code (IaC)
  • Automate creation/changes with Terraform through a CI/CD pipeline
  • Set default include/exclude sink filters applied to every project
  • Deep Terraform (state, editions) lives in the Terraform section
3Aggregate & store your org's logs
  • Aggregate into one/few user-defined Cloud Logging buckets
  • Set a default storage region for residency; set a retention period
  • Add CMEK if default encryption-at-rest is not enough
4Plan & configure exports
  • Decide org-wide aggregated exports, then per folder/project
  • Filters apply to ALL logs, not just exports
  • Anything you fully exclude is gone forever
5Principle of least privilege
  • Security = org, Dev = folder, Auditors = scoped views
  • logging.viewer (Admin Activity) vs privateLogViewer (Data Access)
  • Log views per bucket; redact PII with Sensitive Data Protection
All the audit-log best practices in one view. It starts with planning the hierarchy, then five practices: set org-level Data Access, automate with IaC, aggregate and store, plan exports, and enforce least privilege.
DECISIONEnable Data Access audit logs at the organization level?
Enable org-wideComplete record of who accessed, edited, or deleted what, and when
Keep it scopedLogs grow large, bill per GB, and add queries-per-second load
Pick this when: weigh a complete forensic trail against volume, per-GB cost, and QPS load
AudienceWhat they getScope
Security teamlogging.viewer + logging.privateLogViewerOrganization (global)
Dev teamlogging.viewer + logging.privateLogViewerTheir folder only
External auditorsPre-built dashboards, or logging.viewer / BigQuery Data Viewer / Cloud Storage signed URLsScoped views
GotchaData Access logs often contain PII

Data Access logs can leak sensitive data (side-channel through logs). Use least-privilege IAM, and use log views on a bucket to control who sees logs from which projects/users. For PII, run logs through Sensitive Data Protection to redact before viewing - whether live or from a Cloud Storage archive.

Network logging

VPC Flow Logs

VPC Flow Logs record a sample of network flows (5-tuple, bytes, packets) for a subnet - enabled per subnet, off by default. Use for traffic analysis, forensics, and network cost attribution. They land in Cloud Logging.

GotchaFlow Logs are per-subnet, and they sample

Enable on the subnet, not the VM or the whole VPC. They record a sample of packets, not every packet - fine for patterns, not a full packet capture (use Packet Mirroring for that).

Firewall Rules Logging

Firewall Rules Logging logs when a specific firewall rule allows or denies a connection - enabled per rule, off by default. The answer for "which rule blocked this connection?"