Cloud Audit Logs types explained, and how to export them
Admin Activity, Data Access, System Event and Policy Denied audit logs: what each records, retention, the fields that matter, and four ways to export them.
TL;DR. Google Cloud writes four audit logs per project, folder and organization: Admin Activity (configuration changes, always on, 400 days), System Event (Google-initiated changes, always on, 400 days), Data Access (reads and data writes, off by default except some BigQuery services, 30 days) and Policy Denied (security-policy denials, on by default, 30 days). For an investigation, export all four as JSON: Logs Explorer for small periods, gcloud logging read for larger ones, or copy the sink bucket if you have one.
Cloud Audit Logs are the "who did what, where and when" record of the Google Cloud control plane. Every investigation of a Google Cloud project leans on them, so knowing exactly what each type captures, and what it does not, saves hours.
The four audit log types
Google documents four types in the Cloud Audit Logs overview. The log name tells you which one you are looking at: projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2F<type>.
| Type | Log name suffix | Records | Default | Default retention |
|---|---|---|---|---|
| Admin Activity | activity | API calls that modify configuration or metadata: IAM policies, VMs, firewalls, sinks, keys | Always on, cannot be disabled | 400 days (_Required) |
| System Event | system_event | Changes made by Google systems, e.g. live migration of a VM | Always on | 400 days (_Required) |
| Data Access | data_access | Reads of configuration (ADMIN_READ), reads of user data (DATA_READ), writes of user data (DATA_WRITE) | Off, except some BigQuery services | 30 days (_Default) |
| Policy Denied | policy | Access denied because of a security policy, such as VPC Service Controls | On; can be excluded but not disabled | 30 days (_Default) |
Retention comes from the log buckets: the _Required bucket keeps its logs 400 days and its sink cannot be modified or deleted; the _Default bucket keeps 30 days by default (routing overview, quotas and limits).
Two consequences for incident response:
- Anything that changes the project (a new key, a new Owner, a startup script, a deleted sink) is in Admin Activity for over a year, whatever the configuration.
- Anything that reads data (a bucket downloaded object by object, a secret accessed, a token minted for a service account) only exists if Data Access logging was enabled before the incident, and only for 30 days by default. The Data Access limitations article covers this blind spot.
Anatomy of an audit entry
Each entry is a LogEntry with a protoPayload of type google.cloud.audit.AuditLog (AuditLog reference). These are the fields an investigator reads first:
| Field | Why it matters |
|---|---|
timestamp | When the call happened (UTC) |
protoPayload.methodName | What was done, e.g. SetIamPolicy, v1.compute.instances.setMetadata |
protoPayload.serviceName | Which API, e.g. iam.googleapis.com |
protoPayload.authenticationInfo.principalEmail | Who: a user, a service account, a Gmail account |
protoPayload.authenticationInfo.serviceAccountKeyName | Present when a service account authenticated with a user-managed key; ends with the key ID |
protoPayload.authenticationInfo.serviceAccountDelegationInfo | Present when the service account was impersonated; lists the real caller |
protoPayload.requestMetadata.callerIp / callerSuppliedUserAgent | From where, with what client (gcloud, Terraform, a browser) |
protoPayload.resourceName, resource.labels | On what |
protoPayload.status.code | Empty for success; 7 is PERMISSION_DENIED |
protoPayload.serviceData.policyDelta / metadata | The diff: IAM bindingDeltas, auditConfigDeltas, metadata keys added or removed |
The user agent is underrated. A service account that always calls from Terraform/… suddenly calling from google-cloud-sdk gcloud/… on an unknown IP is a strong lead on its own.
How to export audit logs for analysis
Export early. The export guide on the tool page has the same steps in short form; here is the reasoning behind each path.
Logs Explorer download
Good for a few days of a small project. In Logging → Logs Explorer, query:
logName:"cloudaudit.googleapis.com"
Add OR logName:"vpc_flows" if you also want flow logs, choose the time range, then Actions → Download → JSON. Google documents a limit of 10,000 entries per download (Logs Explorer interface): split the period into several downloads and keep every file. Pick JSON, not CSV; CSV loses the nested structure the detections need.
gcloud logging read
The most reliable path for larger exports (gcloud logging reference):
gcloud logging read 'logName:"cloudaudit.googleapis.com"' \
--project=PROJECT_ID --freshness=30d --format=json > audit.json
gzip audit.json
Use --organization=ORG_ID or --folder=FOLDER_ID when an organization-level aggregated sink or folder logs are in scope. Run a second export for logName:"vpc_flows".
Copy a log sink bucket
If a log sink already routes audit logs to Cloud Storage, you have the best evidence: files organised as cloudaudit.googleapis.com/activity/YYYY/MM/DD/…json, one JSON object per line, going back as far as the sink existed. Copy it with gcloud storage cp -r gs://BUCKET . and keep the folder layout. Sinks do not backfill: they only contain entries written after their creation (configure sinks). If you need older entries still held in a log bucket, Google documents copying log entries to Cloud Storage.
BigQuery sink
With a BigQuery sink, query the cloudaudit_googleapis_com_activity and cloudaudit_googleapis_com_data_access tables for the period and save the result as newline-delimited JSON. The analyzer maps the protopayload_auditlog columns back onto the LogEntry shape. It does not read Avro or Parquet exports.
What about VPC Flow Logs?
VPC Flow Logs are not audit logs: they are sampled network flow records (compute.googleapis.com/vpc_flows) written only for subnets where they were enabled. Export them the same way and analyze them together with the audit logs so that caller IPs can be matched with traffic. See VPC Flow Logs analysis.
Checklist before you start analyzing
- The period covers the suspected intrusion plus a baseline of normal activity (a week or more).
- All four audit types are included, for every project involved, plus organization-level logs if IAM or organization policies might have changed.
- Formats are JSON or JSON lines, gzipped or not. Keep original files untouched and work on copies.
- You noted whether Data Access logs were enabled, and for which services. Absence of evidence in reads is meaningless without that note.
Then drop the files on the analyzer, as described in the step-by-step guide.
Frequently asked questions
Which Cloud Audit Logs are enabled by default?
Admin Activity, System Event and Policy Denied audit logs are always written and cannot be disabled. Data Access audit logs are disabled by default for all services except some BigQuery services (configure Data Access audit logs).
How do I export more than 10,000 log entries?
The Logs Explorer download stops at 10,000 entries. Use gcloud logging read with --format=json, copy the Cloud Storage bucket a sink writes to, or export from a BigQuery sink as newline-delimited JSON.
Further reading
- Cloud Audit Logs overview — Google Cloud documentation.
- Best practices for Cloud Audit Logs — Google Cloud documentation.
- Google Cloud incident response: a compromised project — where these logs fit in the investigation.