Safeguard
Security Guides•

Row access policies in a data warehouse, explained

Row access policies filter which rows each user sees at query time. Here is how they work, where they surprise people, and how to test them.

Safeguard Security Team
4 min read

A row access policy is a rule attached to a table or view that decides, at query time, which rows a given user or role can see. The data stays in one table. Each query is filtered by the policy, so a regional analyst sees only their region without a separate copy of the data.

How the idea works

Without row level controls, teams copy a table once per audience: one extract for EMEA, one for the US, one for finance. Every copy is another place to forget a delete request or a revoked user.

A policy replaces the copies. In Snowflake, a row access policy is a schema level object that you attach to a table or view, and it controls which rows a query returns. The policy expression can be as simple as a check on the current role, or it can look up entitlements in a mapping table. BigQuery works the same way in spirit: each policy lists grantees and a filter expression that behaves like a WHERE clause.

Things that surprise people

Snowflake evaluates the policy using the policy owner's role, not the querying user's. That means users do not need any access to the mapping table the policy reads. It also means the mapping table becomes a sensitive object. Whoever can edit it can change who sees what.

Policies filter reads. The Snowflake documentation notes that row access policies do not currently prevent rows from being inserted, so a user can write a row they could not later read. If your threat model includes bad writes, you need a separate control.

Order matters too. In Snowflake, row access policies are evaluated before masking policies, and for nested views the policy on the underlying table runs first. If you stack policies on views, draw the evaluation order on paper before you trust the result.

In BigQuery, a principal who is not in any policy's grantee list sees no rows at all. When you add a restrictive policy to a table that people already query, anyone who previously had full access needs a policy with a TRUE filter to keep it. Forgetting this is a common way to break a dashboard on a Friday afternoon.

Performance and cost

Row filters are not free. Snowflake notes that queries such as COUNT(*) can be slower because precomputed statistics cannot be used. BigQuery notes that filters do not benefit from partition or cluster pruning and that subquery based policies can raise query cost. Measure a few representative queries before and after.

A short test plan

  1. Create three test identities: a normal user, a user in no group, and an admin.
  2. Run the same query as each and record the row counts.
  3. Join the protected table to an unprotected one and check that the join does not leak counts.
  4. Query through every path your team uses: the console, BI tool, notebook and scheduled jobs.
  5. Re-run the test after each schema change, because replacing a table can drop its policies. BigQuery documents that CREATE OR REPLACE TABLE removes existing policies.

Keep the tests in version control and run them in CI against a non production copy.

Where Safeguard fits

Warehouse policy lives in the warehouse. Safeguard helps around it: asset discovery to find the data tools and integrations in your estate, and compliance and evidence automation to record that access reviews and tests ran. You can also run a free scan at https://gold.safeguard.sh/scan on the repositories that hold your pipeline code.

Quick check

Does a row access policy stop someone from inserting rows they cannot see?

Not necessarily. Snowflake documents that row access policies do not currently prevent rows from being inserted, so write controls need to be handled separately.

Can a table replace operation remove my policies?

In BigQuery, yes. CREATE OR REPLACE TABLE removes existing row access policies, so re-test after any such change.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.