Join our Newsletter — 33% off our NHI Course
Home› Guides› BigQuery Security Guide: IAM, Row and Column Security…
Guide Data Security

BigQuery Security Guide: IAM, Row and Column Security and Exfiltration Controls

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 26 October 2026 15 min read
On this page

BigQuery makes it easy to put an organisation's most sensitive data in front of thousands of users and service accounts, and just as easy to copy it out again with one query or one export job. There is no cluster to harden: security in BigQuery is almost entirely identity and policy, spread across Google Cloud IAM, dataset access, policy tags, row access policies, VPC Service Controls and organisation policies. This guide explains how those layers combine, which predefined roles quietly include export rights, how to apply row and column security correctly, how to stop data leaving the perimeter, and what to log and measure. It is for cloud security engineers, data platform owners and auditors working with BigQuery in production.

Key takeaways

  • Reading data and running queries are separate rights. bigquery.jobs.create (BigQuery Job User) is granted on a project; table data rights are granted on datasets or tables. Design both deliberately.
  • Data Viewer can export. roles/bigquery.dataViewer includes bigquery.tables.export, so "read only" access is also an exfiltration path unless a perimeter constrains it.
  • Row access policies deny by default. Once a table has any row access policy, principals not in a grantee list see no rows, so plan a TRUE filter for jobs that need full access.
  • Column security needs two permissions. Policy tags with Fine-Grained Reader are enforced on top of dataset access, and SELECT * fails for users without it.
  • VPC Service Controls is the exfiltration control. IAM decides who can read; a service perimeter around bigquery.googleapis.com decides where the data can go.

How BigQuery access works

BigQuery has no database users of its own. Every request is made by a Google Cloud principal (user, group, service account or federated workload identity) and evaluated against IAM allow policies on the organisation, folder, project, dataset, table, view or routine, plus fine-grained policies on columns and rows.

LayerQuestion it answersControls
Resource hierarchy IAMWho can run jobs and administer BigQuery in this project?roles/bigquery.jobUser, roles/bigquery.admin at project or folder
Dataset and table IAMWho can read or change this data?dataViewer, dataEditor, dataOwner, metadataViewer on datasets, tables and views
Fine-grained policiesWhich columns and rows can this principal see, clear or masked?Policy tags, data policies and masking, row access policies
Sharing patternsHow do consumers see a subset without source access?Authorized views, authorized datasets, authorized routines
Perimeter and organisation policyWhere can requests come from and where can data go?VPC Service Controls, domain-restricted sharing, CMEK constraints

Because jobs run in one project and read data in another, a common pattern is a "compute" project where analysts hold Job User and "data" projects where they hold dataset-level read roles. Cost and quotas sit with the compute project, data ownership with the data project. The wider IAM model is covered in the Google Cloud IAM and Service Accounts Guide.

Choosing IAM roles

Predefined roleKey permissionsGrant whereSecurity note
BigQuery Job User (roles/bigquery.jobUser)bigquery.jobs.createProject, folder or organisation onlyLets the principal run queries billed to the project; combine with data roles granted elsewhere
BigQuery Metadata Viewer (roles/bigquery.metadataViewer)tables.get, tables.list, datasets.get, routines.get; no data readDataset, table or higherGood for catalogue and discovery users
BigQuery Data Viewer (roles/bigquery.dataViewer)tables.getData, tables.export, tables.replicateData, tables.createSnapshotDataset, table, view or higherIncludes export; grant on datasets, not projects
BigQuery Data Editor (roles/bigquery.dataEditor)getData, updateData, export, tables.createDataset, table or higherCan overwrite tables, which removes row access policies (see below)
BigQuery Data Owner (roles/bigquery.dataOwner)Full dataset and table rights including setIamPolicyDataset or higherCan grant access to others; treat as privileged
BigQuery Admin (roles/bigquery.admin)All bigquery.* permissionsProject, folder, organisationBreak-glass and platform team only
BigQuery Connection User (roles/bigquery.connectionUser)connections.useConnection or higherExternal connections reach Cloud SQL, Spanner or other clouds with the connection's own service account
  • Grant to groups, not individuals: dataset ACLs that list individual users drift quickly and are hard to review.
  • Avoid project-level data roles: dataViewer at project level silently covers every future dataset in the project.
  • Use custom roles where export is not needed: a custom role without bigquery.tables.export removes the extract job path for that population. Queries can still return results, so this is a complement to, not a replacement for, a perimeter.
  • Block public sharing: the organisation policy constraint iam.managed.allowedPolicyMembers (or the legacy iam.allowedPolicyMemberDomains) restricts IAM grants to principals from your organisation and blocks allUsers and allAuthenticatedUsers unless you build a tagged exception with a custom constraint. See the Google Cloud Organization Policy Guide.

Service accounts and workload access

Most BigQuery traffic in a mature estate comes from machines: scheduled queries, Dataflow and Composer pipelines, BI connectors, notebooks and, increasingly, AI agents querying data on a user's behalf. Each of these is a non-human identity with data access of its own.

  • One service account per workload: a shared "bigquery-etl" account with dataEditor on every dataset makes it impossible to scope or attribute access.
  • No downloadable keys: use attached service accounts, Workload Identity Federation for workloads outside Google Cloud, and service account impersonation for people. Leaked service account keys are the most common way BigQuery data is reached from outside. See the Google Cloud Service Account Keys Security Guide and the Workload Identity Federation Guide.
  • BI and SaaS connectors: OAuth grants and connector service accounts often hold broad read. Give each connector a dedicated identity with dataset-level access to curated datasets only.
  • The encryption service account: with CMEK, BigQuery uses a Google-managed service account ([email protected]) that needs roles/cloudkms.cryptoKeyEncrypterDecrypter on the key. That grant is legitimate; monitor for others.

Column-level security and data masking

Column-level access control uses policy tags organised in taxonomies in Data Catalog (Dataplex). You tag a column with a policy tag, enforce access control on the taxonomy, and grant the Fine-Grained Reader role (datacatalog.categoryFineGrainedReader) on the policy tag to those allowed to read clear values.

  • Two checks: users need dataset access and policy tag access. Without Fine-Grained Reader, SELECT * fails and names the restricted columns; users can still query the other columns with SELECT * EXCEPT.
  • Limits to plan around: one policy tag per column, at most 1,000 unique policy tags per table, hierarchies up to five levels, and the taxonomy must be in the same location as the table. Taxonomies cannot be referenced across organisations.
  • Writes: inserts do not need fine-grained read, but updates, deletes and merges need it on the columns they read.
  • Authorized views: policy tags on the underlying table columns are still checked, so an authorized view does not bypass column security.
  • Dynamic data masking: data policies on a policy tag let a masked-reader population see masked values (for example nullified, hashed or default values) instead of being refused. Masking keeps queries and dashboards working for analysts who do not need raw values.
  • Separation of duties: Data Catalog Policy Tag Admin (datacatalog.categoryAdmin) manages taxonomies; BigQuery Data Policy Admin, BigQuery Admin or Data Owner manage data policies. Keep taxonomy administration with the data governance function, not the pipeline team.

Row-level security

A row access policy is created with CREATE ROW ACCESS POLICY on a table, naming a GRANT TO list of principals and a FILTER USING predicate that works like a WHERE clause. BigQuery Admin and Data Owner can create them.

  • Deny by default: as soon as one policy exists, principals not in any grantee list see no rows. Anyone who had full access before needs a policy with FILTER USING (TRUE), including service accounts that run copies and other non-query operations.
  • Overwrites remove policies: CREATE OR REPLACE TABLE and WRITE_TRUNCATE loads remove existing row access policies; TRUNCATE TABLE does not. A pipeline that rebuilds a table nightly will silently strip row security unless it recreates the policies. Test for this explicitly.
  • Limitations: GoogleSQL only (legacy SQL is rejected); no policies on JSON columns or temporary tables; wildcard table queries, table sampling and previews are not supported; partition and cluster pruning does not apply to the filter; subquery policies have a 100 MB limit on the top-level subquery result, and data masking works only with non-subquery policies.
  • Region copies: tables with row-level or column-level security cannot be copied across regions.

Choosing the pattern

NeedPatternTrade-off
Hide a sensitive column from most usersPolicy tag plus Fine-Grained ReaderSELECT * breaks for non-readers, so expect query changes
Show a sensitive column maskedPolicy tag with a data masking policyMasked values must still be safe if combined with other columns
Restrict rows by region, tenant or business unitRow access policiesPipelines that replace tables must recreate policies
Give a team a curated subset without source accessAuthorized view or authorized datasetMost flexible and best performance; up to 2,500 authorised resources per dataset
Strongest isolationSeparate tables or datasetsMost secure, least flexible, duplicated data

Preventing exfiltration

An identity that can read data can usually also copy it: query results to a table in another project, extract jobs to Cloud Storage, table copies and snapshots, or BI tool downloads. The relevant ATT&CK techniques are T1530 Data from Cloud Storage, T1537 Transfer Data to Cloud Account and T1567 Exfiltration Over Web Service.

  1. Service perimeter: put data projects in a VPC Service Controls perimeter with bigquery.googleapis.com (and storage.googleapis.com if exports go to Cloud Storage) as restricted services. Requests that would read data into or write data out to a project outside the perimeter are blocked unless an ingress or egress rule allows them.
  2. Access levels for ingress: define access levels (for example corporate IP ranges or managed devices) and ingress rules so that a stolen credential used from elsewhere is refused even when IAM allows the call.
  3. Narrow egress rules: where a project must query data in another perimeter, write an egress rule for that project, identity and method, not for all BigQuery methods.
  4. Dry run first: run perimeter changes in dry-run mode, review the violation logs for a few weeks, then enforce.
  5. Remove export from roles that do not need it and keep public sharing blocked with domain-restricted sharing.

Authorized views across perimeters need ingress and egress rules covering both the view's project and the source project, and revoking authorisation can surface as perimeter violations. For the wider control set see the Data Exfiltration Guide.

Encryption and keys

BigQuery encrypts data at rest by default using envelope encryption managed by Google. Customer-managed encryption keys (CMEK) put the key encryption key in Cloud KMS under your control, so disabling the key makes the data unreadable and every use is visible in Cloud KMS audit logs.

  • Location: key rings must match the dataset location (multi-region keys for multi-region datasets).
  • Setting keys: set a dataset default key or specify kms_key_name in CREATE TABLE, or use the bq --destination_kms_key flag. BigQuery always uses the primary key version.
  • Query results: results go to a temporary table encrypted with a Google-managed key unless a project default key or an explicit CMEK applies. Set the project default where results are themselves sensitive.
  • Cost and dependency: each query on a CMEK table makes a Cloud KMS decrypt call, and key availability becomes data availability. Protect key administration rights at least as tightly as data rights.
  • Field-level protection: AEAD encryption functions allow encrypting individual values with keysets, useful for crypto-shredding per customer. See the Cryptographic Key Management Guide.

Logging, detection and metrics

SourceWhat it gives youUse
Cloud Audit Logs, Admin ActivityDataset, table, IAM policy and policy changessetIamPolicy on datasets, row access policy deletion, perimeter changes
Cloud Audit Logs, Data AccessData reads and job execution; BigQuery Data Access logs cannot be disabledWho queried what; prefer the BigQueryAuditMetadata format
INFORMATION_SCHEMA.JOBS viewsPer-job detail including bytes and slots used and referenced tablesVolume anomalies, unusual tables per principal
VPC Service Controls violation logsBlocked or dry-run requests crossing the perimeterExfiltration attempts and policy tuning
Cloud KMS audit logsKey use, disable and destroyCMEK tampering

Audit logs contain SQL text and schema details, so restrict who can read them and route them to a central log project with a sink. See the Cloud Logging and Audit Trail Guide.

Detections worth building: extract jobs or table copies to projects outside the organisation; a principal querying far more bytes or tables than its baseline; dataset IAM grants to external domains; row access policy drops; service account key creation for identities with BigQuery data roles; perimeter violations from an identity with valid IAM.

Metrics:

  • Percentage of sensitive datasets inside an enforced service perimeter.
  • Number of principals holding dataViewer or higher at project level (target zero outside the platform team).
  • Percentage of regulated columns carrying an enforced policy tag.
  • Service accounts with BigQuery data roles that have user-managed keys (target zero).
  • Row access policy coverage on multi-tenant tables, checked after each pipeline run.

Implementation roadmap

  1. Inventory: list datasets with their IAM bindings, project-level BigQuery roles, service accounts and keys, connections, authorized views and external shares. Classify datasets by sensitivity.
  2. Guardrails: apply domain-restricted sharing and disable service account key creation at organisation level, with exceptions documented. Test on a pilot folder first; roll back by removing the policy from that folder.
  3. Re-grant by dataset: move data roles from projects to datasets and groups, split compute and data projects, create custom roles without export where it is not needed.
  4. Fine-grained security: build the policy tag taxonomy with the data governance team, tag regulated columns, enforce in a test project, then production. Add row access policies to multi-tenant tables and update pipelines that use WRITE_TRUNCATE or CREATE OR REPLACE TABLE to recreate them.
  5. Perimeter: create VPC Service Controls perimeters in dry-run mode, review violations, add precise ingress and egress rules, then enforce. Rolling back means returning the perimeter to dry run.
  6. Keys and logging: CMEK for regulated datasets, project default keys for results, log sinks to a central project, detections and metrics live.

Small versus large organisations: a small team can get most of the value from dataset-level group grants, a single policy tag taxonomy and domain-restricted sharing. A large organisation with many data products needs separate compute and data projects, perimeters per data domain, a governed taxonomy owner, automated row policy checks in CI for pipelines, and access reviews tied to the Access Reviews Guide process.

Framework mapping

Control areaNIST SP 800-53 Rev 5NIST CSF 2.0ISO/IEC 27001:2022 Annex AATT&CK threat addressed
IAM roles, service accounts, no keysAC-6, IA-2, IA-5PR.AA-05A.5.15, A.5.18, A.8.2T1078.004 Cloud Accounts, T1552.001 Credentials In Files
Policy tags, masking, row access policiesAC-3PR.AA-05A.8.3, A.8.11T1213 Data from Information Repositories
VPC Service Controls, domain-restricted sharingAC-4, SC-7PR.DS-01A.8.12, A.8.22T1537, T1567, T1530
CMEK and in-transit protectionSC-12, SC-28, SC-8PR.DS-01, PR.DS-02A.8.24Unauthorised storage access
Audit logs and job monitoringAU-2, AU-12DE.CM-03, DE.CM-09A.8.15, A.8.16All of the above

In CIS Controls v8.1 the work maps mainly to Control 3 (Data Protection), Control 6 (Access Control Management) and Control 8 (Audit Log Management).

Common failure patterns

  • Read-only that is not read-only: Data Viewer granted at project level to a large group, with no perimeter, gives everyone the ability to export every current and future table.
  • Row security stripped by pipelines: a nightly CREATE OR REPLACE TABLE removes the row access policies and every analyst sees every tenant's rows until someone notices.
  • Service account keys in notebooks and repos: a key for a pipeline account with dataEditor gives an outsider full access from anywhere when no perimeter or access level applies. The Okta support system breach shows how one service account credential stored in the wrong place exposes many customers.
  • Credentials without strong authentication: the Snowflake breach showed infostealer credentials without MFA or network restrictions unlocking 165 data warehouses; the lesson for BigQuery is MFA for people, no keys for machines, and access levels on the perimeter.
  • Perimeter left in dry run: a VPC Service Controls perimeter tested in dry-run mode and never enforced logs exfiltration rather than stopping it.
  • Public datasets by accident: allAuthenticatedUsers on a dataset, often added for a demo, exposes data to any Google account. Domain-restricted sharing prevents it.

Practitioner checklist

  • Separate compute (Job User) and data (dataset roles) projects, and grant data roles to groups at dataset level.
  • Remove project-level dataViewer, dataEditor and dataOwner outside the platform team.
  • Enforce domain-restricted sharing and block service account key creation at organisation level.
  • Give each pipeline, BI connector and agent its own service account with no user-managed keys.
  • Tag regulated columns with enforced policy tags; use masking where analysts need the column shape.
  • Add row access policies to multi-tenant tables, with a TRUE filter for named service accounts, and test that pipelines recreate them.
  • Place sensitive data projects in an enforced VPC Service Controls perimeter with narrow ingress and egress rules.
  • Use CMEK for regulated datasets and query results, and alert on Cloud KMS key disable and destroy.
  • Sink audit logs centrally, restrict who can read them, and build detections on exports, copies and IAM changes.
  • Review dataset access and authorized views quarterly.

Standards and references

Related NHI Mgmt Group resources: Google Cloud Security Guide · Data Security Guide · Amazon Redshift Security Guide · Snowflake Security Guide · Data Loss Prevention (DLP) Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 26 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org