Audit logs and org-wide log sinks

Google Cloud · Expert · 14 min

Incident response and compliance depend on knowing who did what, where, and having that record outside the reach of attackers.

Cloud Audit Logs record API activity on Google Cloud resources. Four types:

  • Admin Activity: configuration and metadata changes (create VM, set IAM policy). Always on, free, cannot be disabled; kept 400 days in _Required.
  • Data Access: reads of configuration and reads or writes of user data. Off by default for most services (BigQuery is the notable exception), because volume and cost can be large. Enable per service and log type (ADMIN_READ, DATA_READ, DATA_WRITE) in the IAM policy's auditConfigs, ideally at org level for sensitive services.
  • System Event: Google-initiated changes such as live migration. Always on.
  • Policy Denied: requests refused by VPC Service Controls or org policy.

Each entry's protoPayload holds methodName, resourceName, authenticationInfo.principalEmail, caller IP and the request.

Centralise them: an aggregated sink at the org or a folder with --include-children routes logs from every current and future project to one destination: a BigQuery dataset for analysis, a log bucket with Log Analytics and a locked retention policy, or Pub/Sub for a SIEM. Grant the sink's writer identity write access on the destination. Keep the destination in a dedicated security project that workload admins cannot touch.

Remember that audit logs show caller identities; with service account impersonation, serviceAccountDelegationInfo shows the original human.

Example

# Who changed IAM policies in prod this week?
gcloud logging read '
  logName:"cloudaudit.googleapis.com%2Factivity"
  AND protoPayload.methodName="SetIamPolicy"' \
  --project=shop-prod-1234 --freshness=7d \
  --format="table(timestamp,protoPayload.authenticationInfo.principalEmail,protoPayload.resourceName)"

# Route every audit log in the org to BigQuery in a security project
gcloud logging sinks create org-audit \
  bigquery.googleapis.com/projects/sec-logs-1234/datasets/org_audit \
  --organization=555555555555 --include-children --use-partitioned-tables \
  --log-filter='logName:"cloudaudit.googleapis.com"'

gcloud logging sinks describe org-audit --organization=555555555555 --format="value(writerIdentity)"
# serviceAccount:service-org-...@gcp-sa-logging.iam.gserviceaccount.com
# -> grant it roles/bigquery.dataEditor on the org_audit dataset

Remember

  • Admin Activity is always on and free; Data Access is mostly off until enabled
  • Aggregated sinks with --include-children cover future projects too
  • Store audit logs in a separate, locked-down project

Watch out for

  • Assuming reads of sensitive data are logged when Data Access logs were never enabled for that service.

Check yourself

  1. A secret was read last week and you need to know by whom, but nothing appears in logs. Most likely reason?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: cloud.google.com/logging/docs/audit

Builds on

Unlocks

Nothing builds on this yet.