CertSafari
    Databricks Certified Data Engineer Associate· Lessons

    Domain 7 · Lesson 32/33

    ABAC Policies for Row Filtering and Column Masking at Scale

    Understand column-level masking and row-level security

    8 min read
    3.75% of exam
    2 sources
    Published 2 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Explain why Databricks recommends ABAC policies over per-table filters and masks when many tables need the same rules
    • Read and write a CREATE POLICY statement for a row filter or a column mask, including TO, EXCEPT, WHEN and MATCH COLUMNS
    • Choose between table-level filters and masks, ABAC policies and dynamic views for a given requirement
    • Apply the main performance guidance for filter and mask UDFs

    1.From per-table functions to tag-driven policies

    Row filters drop the rows a user shouldn't see. Column masks replace sensitive values for users who shouldn't see them. You can attach either one table at a time with ALTER TABLE. That works for a handful of tables, but each new table needs its own setup, and the table owner controls that setup.

    Attribute-based access control (ABAC) policies work differently. You attach a policy once to a catalog or a schema. It then applies automatically to every table and column carrying the right governed tags. A table tagged sensitivity:high tomorrow is covered as soon as it has the tag, and nobody has to edit it.

    No. This separation of duties is a large part of why ABAC exists. Policies can be defined by higher-level admins, and table owners can't override or remove them. Policy logic is also evaluated more efficiently than table-specific UDFs. Creating, editing or deleting a policy requires MANAGE on the securable object or ownership of it. Policies also need Databricks Runtime 16.4 or above, or serverless compute.

    Checkpoint 1 of 4· Check yourself

    A company must mask every column tagged as PII across 300 tables in a schema. New tables are added weekly. Which statement best describes the benefit of an ABAC policy attached at the schema level over per-table column masks?

    Checkpoint 2 of 4· Exam question

    A data engineer runs `ALTER TABLE finance.transactions_view SET ROW FILTER region_filter ON (region)` against a view built on top of the `transactions` table, expecting it to restrict rows by region for downstream analysts. What will happen?

    Sources12

    2.Anatomy of a CREATE POLICY statement

    An ABAC policy answers four questions: where it is attached, who it applies to, which tables and columns it targets, and what function does the work. The function is still a Unity Catalog UDF that you need EXECUTE on. A row filter function returns a boolean, and a mask function returns a value castable to the column type. In SQL, each question maps to a clause:

    - ON CATALOG | SCHEMA | TABLE: the scope. The policy evaluates against every descendant table, including views. Databricks recommends attaching at the highest level that applies. - TO / EXCEPT: the users, groups or service principals subject to the policy, and the ones exempt from it. Exempt principals see the full, unmodified data. - WHEN: which tables in scope qualify, based on their tags, using has_tag and has_tag_value. Leave it out and every table in scope matches. - MATCH COLUMNS ... AS alias: tag conditions that pick out the columns. A policy can have up to 3 of these, and all of them must match. - ON COLUMN (masks only) and USING COLUMNS: which matched column to mask, and what arguments to pass to the UDF.

    Row filter policy: hide EU rows from US analysts, only on tables tagged sensitivity:highsql
    CREATE POLICY hide_eu_customers
    ON SCHEMA prod.customers
    COMMENT 'Exclude rows with European customers from sensitive tables'
    ROW FILTER non_eu_region
    TO us_analysts
    FOR TABLES
    WHEN has_tag_value('sensitivity', 'high')
    MATCH COLUMNS has_tag('geo_region') AS region
    USING COLUMNS (region);

    The policy above never names a column. Whatever column carries the geo_region tag becomes region and is passed to non_eu_region, which returns geo_region <> 'eu'. The column mask policy below works the same way. Any column tagged pii:ssn gets masked down to its last 4 characters for us_analysts, while one group is exempt.

    Checkpoint 3 of 4· Fill the gap

    Which keyword exempts the admins group from this column mask policy?

    CREATE POLICY mask_ssn
    ON SCHEMA prod.customers
    COLUMN MASK ssn_to_last_nr
    TO us_analysts  ?  admins
    FOR TABLES
    MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn
    ON COLUMN ssn
    USING COLUMNS (4);

    Sources2

    3.Choosing an approach and keeping it fast

    Unity Catalog gives you three ways to restrict what users see. The deciding questions are how many tables the rule covers and whether users should query the base table at all.

    Three approaches to row- and column-level access control
    ApproachApplies toManaged usingBest used for
    Table-level row filters and column masksIndividual tables and columnsALTER TABLE by the table owner or a user with MANAGETable-specific logic
    ABAC policiesTables and columns matched by tag conditionsCREATE POLICY attached to a catalog, schema, or tableCentralized rules applied automatically across many tables
    Dynamic viewsA view built from one or more base tablesSQL logic in the view definitionSharing a curated or transformed version of the data

    Checkpoint 4 of 4· Match them up

    Match each requirement to the approach that best fits it

    Tap a term, then the definition that fits it.

    Whichever approach you use, the engine guarantees that users can't see base-table values before filtering or masking is applied. When it has to choose between an optimization and preventing a leak, it always takes the secure option, and that can slow queries down. The guidance for keeping the cost low:

    - Keep UDFs simple. Prefer a simple CASE over mapping tables or expression subqueries. - Use few UDF arguments. Databricks can't optimize away columns passed as arguments, even when the query doesn't use them. - Limit distinct masks on large tables. Mask only the truly sensitive columns and reuse masking functions. - Avoid long AND chains in row filters. Only one distinct row filter resolves for a given user and table, so logic tends to get combined with AND. - Use expressions that can't throw. An error such as division by zero could reveal values, so prefer try_divide. - Prefer SQL to Python UDFs. If you must use Python, mark the UDF DETERMINISTIC where it applies.

    Sources1

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.A table owner can remove an ABAC row filter or column mask that applies to their table, just as they can drop a table-level filter.Why is that wrong?

      ABAC policies can be defined by higher-level admins, and table owners can't override or remove them. This separation of duties is one of the main reasons to choose ABAC.

      Covered in From per-table functions to tag-driven policies

    2. 2.CREATE OR REPLACE POLICY updates only the clauses you include, leaving the rest of the policy unchanged.Why is that wrong?

      It replaces the entire policy definition, so every clause must be restated. Partial updates are only available through the SDK's update_policy with update_mask.

      Covered in Anatomy of a CREATE POLICY statement

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Policy logic is also evaluated more efficiently than table-specific UDFs.”
      ↩︎ From per-table functions to tag-driven policies
      “Prefer simple CASE expressions over mapping tables or expression subqueries.”
      ↩︎ Choosing an approach and keeping it fast
      “Databricks cannot optimize away column references that come from UDF arguments”
      ↩︎ Choosing an approach and keeping it fast
      “Only one distinct row filter can resolve at runtime for a given user and table”
      ↩︎ Choosing an approach and keeping it fast
      “can be defined by higher-level admins, so table owners can't override or remove them”
      ↩︎ Exam trap 1
      “ABAC policies attach at the catalog or schema level and apply automatically based on governed tags, rather than requiring per-table configuration.”
      ↩︎ Checkpoint
      “expose a curated, transformed, or joined version of your data to users who don't have access to the underlying tables”
      ↩︎ Checkpoint
    2. 2.
      “Modifying policies (create, edit, delete) requires MANAGE on the securable object or object ownership.”
      ↩︎ From per-table functions to tag-driven policies
      “Databricks Runtime 16.4 or above, or serverless compute.”
      ↩︎ From per-table functions to tag-driven policies
      “The policy evaluates against all tables, including views, that are descendants of this securable object.”
      ↩︎ Anatomy of a CREATE POLICY statement
      “Exempt principals are not subject to filtering or masking and see the full, unmodified data.”
      ↩︎ Anatomy of a CREATE POLICY statement
      “If omitted, defaults to TRUE (applies to all tables in scope).”
      ↩︎ Anatomy of a CREATE POLICY statement
      “A policy can include up to 3 MATCH COLUMNS expressions, and all must match for the policy to apply.”
      ↩︎ Anatomy of a CREATE POLICY statement
      “Databricks recommends attaching policies at the highest applicable level.”
      ↩︎ Anatomy of a CREATE POLICY statement
      “CREATE OR REPLACE POLICY replaces the entire policy definition. Specify all clauses, not just the fields you want to change.”
      ↩︎ Exam trap 2

    Ready to test yourself?

    Practise the 15 questions on this subdomain.

    Spotted a mistake, or was something unclear? Tell us.