Skip to content

feat(bigquery): support row_access_policy config for BigQuery tables #2221

Open

Description

@kevin-hu-datascience

Feature request

Description

The row_access_policy field exists in dbt-core's model config JSON schema and is implemented by the Snowflake and Databricks adapters, but the BigQuery adapter does not support it.

BigQuery supports Row-Level Security via CREATE ROW ACCESS POLICY, which allows filtering rows based on the querying principal (SESSION_USER()). This is useful for data governance scenarios such as consent-based filtering, multi-tenant isolation, and role-based access control.

The problem

BigQuery drops row access policies when a table is rebuilt via CREATE OR REPLACE TABLE — which is what dbt does for materialized='table' and materialized='incremental' with --full-refresh. This makes it impossible to maintain RLS policies declaratively through dbt.

The BigQuery adapter already solves an analogous problem for column-level security: policy_tags are re-applied after every table build via persist_docs → _update_column_dict. Row access policies need the same treatment.

Proposed solution

Add a row_access_policy config key to the BigQuery adapter that:

  1. Accepts a dict with filter_using (SQL predicate), grantees (list of principals), and an optional policy_name
  2. After every table/incremental/view materialization, drops the dbt-managed policy (by name) and re-creates it
  3. Follows the same lifecycle as policy_tags — declarative config, re-applied after every build

Example usage

{{ config(
    materialized='table',
    row_access_policy={
        'filter_using': 'org_id NOT IN (SELECT org_id FROM `project.dataset.optouts`)',
        'grantees': ['serviceAccount:ai-bot@project.iam.gserviceaccount.com'],
        'policy_name': 'consent_filter',
    }
) }}

Who would benefit

Teams using BigQuery's native RLS for data governance. Currently the only workaround is maintaining separate filtered views (governed facades), which is error-prone and doesn't scale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions