Auditing BigQuery access logs is the practice of collecting, querying, and analyzing Cloud Logging records that describe every read, write, and metadata operation performed in Google BigQuery.
Auditing BigQuery Access Logs
Learn how to capture, query, and interpret Google BigQuery access logs to secure data, control spend, and maintain compliance.
BigQuery access logs are records automatically written to Cloud Logging whenever a user or service account interacts with BigQuery. Each log entry is a JSON object that includes who performed the action (principalEmail
), what was done (methodName
), which resource was touched (resourceName
), when it happened (timestamp
), and several context-rich sub-objects. Combined, these logs offer a forensic trail for every jobs.query
, tabledata.list
, or tables.get
call—even failed attempts.
Regularly reviewing access logs enables you to:
At a minimum, every entry has:
protoPayload.authenticationInfo
– User, service account, or workload identity.protoPayload.serviceName = "bigquery.googleapis.com"
protoPayload.methodName
– e.g. jobservice.jobcompleted
, tableservice.gettable
.resource.labels
– Project number, dataset ID, table ID.protoPayload.metadata.jobChange.job.jobConfig.queryConfig.query
– The actual SQL for queries.Understanding the schema allows precise filters that reduce noise and speed up investigation.
BigQuery audit logs are enabled by default for all projects, but only retained for 30 days in Cloud Logging. For long-term analytics you should:
resource.type = "bigquery_resource"
to a dedicated BigQuery dataset (often called audit_logs
)._PARTITIONTIME
pseudo-column (or timestamp
field) to avoid costly full scans.Once ingested into BigQuery, logs become first-class citizens ready for SQL. A common pattern is to wrap the raw table in LOGICAL
views that surface only the fields you need. Below is a starter query that returns every successful query job in the past 24 hours:
SELECT
TIMESTAMP_TRUNC(protoPayload.timestamp, HOUR) AS hour_bucket,
protoPayload.authenticationInfo.principalEmail AS actor,
job.jobStatistics.totalProcessedBytes / POW(2, 30) AS processed_GB,
job.jobConfig.queryConfig.query AS sql_text
FROM `my_project.audit_logs.cloudaudit_googleapis_com_data_access` AS l,
UNNEST(protoPayload.metadata.jobChange) AS jc,
UNNEST([jc.job]) AS job
WHERE
protoPayload.serviceName = 'bigquery.googleapis.com'
AND protoPayload.methodName = 'jobservice.jobcompleted'
AND protoPayload.status.code = 0 -- success
AND TIMESTAMP(protoPayload.timestamp) > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)
ORDER BY processed_GB DESC;
Look for SELECTs on sensitive tables by unexpected principals or unusually large totalProcessedBytes
. Combine with Cloud Identity information to trigger alerts when a user in the contractor
group scans a PII dataset.
Join jobStatistics.totalBilledBytes
with pricing data to compute spend per user or dashboard. Historical trending makes it easy to see which Looker Studio report exploded in cost after a schema change.
Service accounts should operate predictably. When a data-loading account suddenly performs tableservice.list
calls, you may have leaked credentials. Schedule a daily query that flags new methodName
values per service account.
timestamp
and principalEmail
to minimize read costs.Even experienced teams fall into traps that weaken their audit posture.
tableservice.gettable
and storage.Write
events._PARTITIONTIME
or date range can create runaway bills. Use WHERE _PARTITIONTIME >= ...
in every query or enforce dataset-wide partition filters.Leverage BigQuery scheduled queries to run security checks hourly or daily. Store findings in a security_findings
table and trigger Cloud Functions or Slack notifications on new rows. This forms the backbone of continuous monitoring without extra infrastructure.
Publish summarized data (e.g., bytes processed by user per day) to Looker or Data Studio. Overlay cost thresholds and SLA markers. When an anomaly appears, drill back into the raw logs for root cause analysis.
Because Galaxy is a modern SQL editor, you can point it at the audit_logs
dataset and leverage its AI copilot to draft the complex JSON extraction queries shown above. Store vetted queries in Galaxy Collections so your security team shares one source of truth instead of pasting snippets into Slack.
principal_email
at runtime.Auditing BigQuery access logs transforms raw metadata into actionable intelligence. By exporting logs to BigQuery, applying sound schema design, and automating analysis, teams can tighten security, control cost, and breeze through compliance audits. Pair these practices with Galaxy’s developer-friendly SQL workspace to move from ad-hoc queries to a living, shareable audit framework.
BigQuery holds mission-critical and often sensitive data. Every query or metadata call can expose information or drive unexpected costs. Auditing access logs is the only verifiable way to prove who saw what, when, and how much it cost. It underpins compliance (GDPR, HIPAA, SOC 2), incident response, and financial governance. Without systematic log auditing, organizations fly blind on both security and spend.
Most compliance frameworks recommend at least 180 days. Many enterprises choose 365 days to cover internal and external audits. Configure a log sink to BigQuery or Cloud Storage with lifecycle management to balance retention and cost.
Yes. For successful query jobs the SQL statement appears in protoPayload.metadata.jobChange.job.jobConfig.queryConfig.query
. However, partial statements may be truncated for very large queries.
Absolutely. Point Galaxy's connection at the dataset where you export logs. Galaxy's AI copilot can then help you craft nested JSON extraction queries, and you can share vetted log dashboards via Collections.
Ingestion is free; you pay only for storage and the queries you run. Partitioning and clustering dramatically reduce query cost. Over time, move cold partitions to Cloud Storage if budgets are tight.