What you will be able to do
- Explain how ABAC uses governed tags so that one policy protects many tables, including tables created later
- Describe how governed tags are created, controlled and inherited, including the column-level exception
- Read a CREATE POLICY statement and identify its scope, principals, table condition and column condition
- Choose between an ABAC policy and a table-level row filter or column mask, and recognise when the two conflict
Key concept
Attribute-based access control (ABAC) — Under ABAC, you write a policy once and attach it high in the Unity Catalog hierarchy. It then filters rows or masks columns on every table whose governed tags match its conditions, so you never attach a filter to each table by hand.
1.From per-table rules to tag-driven policies
A row filter or column mask in Unity Catalog is a user-defined function (UDF). For row filters, the UDF decides whether each row is returned. For column masks, it decides what value each user sees in a column. You can attach that function to each table one at a time. That works for a handful of tables, but it does not scale. Every new table needs someone to remember to protect it. ABAC changes the unit of control. Databricks describes ABAC as a model that "uses governed tags and policies to grant permissions based on object attributes rather than per-object grants." You describe the data you want to protect with tags, such as pii or sensitivity. The policy then targets whatever carries those tags. The docs give this example: a policy that masks every column tagged PII in tables inside schemas tagged HR.
ABAC has four policy types. Only two of them handle row-level and column-level security, and those two are the subject of this objective. They are also the only two that need a UDF.
| Policy type | Uses a UDF? | Effect |
|---|---|---|
| Row filter | Yes | Rows where the UDF returns FALSE are excluded from query results |
| Column mask | Yes | UDF returns the original column value or a masked version |
| GRANT | No | Grants privileges dynamically on supported securable types |
| DENY (Beta) | No | Explicitly denies privileges; currently scoped to MANAGE ACCESS CONTROL |
Checkpoint 1 of 6· Check yourself
Which ABAC policy types require a UDF to implement their logic?
Row filter and column mask policies rely on a UDF for their filtering or masking logic. GRANT and DENY policies grant or deny privileges directly and use no UDF.
“Row filter and column mask policies require UDFs to implement the filtering or masking logic.”Source: docs.databricks.com
Sources1
2.Governed tags: the attributes policies match on
In Unity Catalog, the attributes that ABAC policies match on are governed tags. Governed tags are "key-value pairs defined at the account level and applied to Unity Catalog securable objects", such as catalogs, schemas, tables and columns. Because tags are defined at the account level, one tag taxonomy can span every metastore in the account. Each governed tag has a tag policy. The tag policy can limit which values are allowed, and it controls who may assign the tag. Once a key is governed, "only users with the ASSIGN privilege on the department governed tag can assign or modify department tag values." This control is what makes the tags trustworthy enough to drive security: if anyone could retag a column, anyone could unmask it. To create a governed tag you need the CREATE permission at the account level. Account admins and workspace admins have it by default. An account can hold at most 1,000 governed tags.
-- Create a key-only governed tag.
CREATE GOVERNED TAG isPii;
-- Create a governed tag with allowed values.
CREATE GOVERNED TAG sensitivity_level VALUES ('low', 'medium', 'high');
-- Create a governed tag with a description and allowed values.
CREATE GOVERNED TAG pii
DESCRIPTION 'Indicates what kind of personal identifiable information the asset contains'
VALUES ('ssn', 'ccn', 'dob');If you create a governed tag whose key is already in use as an ordinary tag, the existing assignments become governed straight away. You do not have to reassign them. Inheritance is what lets one tag cover a large estate. A tag on a catalog or schema reaches every table beneath it, but it stops at columns. Column tags must be applied directly to each column. Applying them one column at a time does not scale, so Databricks also tags columns automatically. Data Classification applies class.* system tags such as class.us_ssn and class.email_address, described as "a family of system tags that Databricks Data Classification automatically applies to columns containing PII or other sensitive data." One caution: tag data is stored as plain text and may be replicated globally, so tag names and values must never contain sensitive information themselves.
Checkpoint 2 of 6· Check yourself
A steward applies the governed tag sensitivity: high to the hr catalog. Which objects will has_tag_value('sensitivity', 'high') match through inheritance?
Schemas and tables inherit governed tags from their catalog. Individual columns are the one exception and must be tagged directly.
“All objects within a catalog or schema automatically inherit governed tags that you apply to that catalog or schema, except individual table columns.”Source: docs.databricks.com
Checkpoint 3 of 6· Exam question
A Databricks Unity Catalog metastore has been tagged so that every catalog, schema, and table where compliance officers store customer records carries the governed tag `sensitivity=restricted`. The data platform team needs any table under that tag — including tables created next quarter — to automatically show only rows belonging to the querying user's assigned region, without editing each table's DDL as new tables appear. Which approach satisfies this requirement with the least ongoing maintenance?
Correct answer: A — Attach one ABAC policy at the catalog level with `ROW FILTER` and a `WHEN has_tag_value('sensitivity','restricted')` clause, so it reaches every current and future table carrying that tag automatically.
- A. A catalog-level ABAC policy that keys off `has_tag_value('sensitivity','restricted')` is the correct fit because a single policy definition automatically extends to new tables that acquire the tag, with no per-table DDL required.
- B. Manually creating a UDF and running `ALTER TABLE ... SET ROW FILTER` protects only the tables it is explicitly applied to; it does not extend to any table created after this run, so the team would have to repeat the step indefinitely.
- C. A dynamic view adds a filtering layer only in front of the specific view definitions that were built, and it does not retroactively or automatically protect base tables or any table created later, so it does not meet the automatic-scaling requirement.
- D. Splitting data across separate per-region catalogs replaces row-level filtering with physical partitioning of storage, which does not scale automatically to newly tagged tables and requires re-architecting data placement rather than applying a governance policy.
3.Anatomy of a policy: scope, principals, conditions, action
Every row filter or column mask policy answers four questions: where it is attached, who it applies to, which tables and columns it targets, and what it does to them. The example below masks PII columns in HR-tagged tables across a whole catalog. Everyone in account users sees the masked values except HR admins.
CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
RETURN '***';
CREATE POLICY mask_pii_for_hr
ON CATALOG catalog_a
COLUMN MASK mask_pii
TO `account users` EXCEPT `HR admins`
FOR TABLES
WHEN has_tag('HR')
MATCH COLUMNS has_tag('PII') AS pii_col
ON COLUMN pii_col;**Scope (ON).** A row filter or column mask policy can be attached to a CATALOG, SCHEMA or TABLE, or to the METASTORE (Beta). It is then evaluated against every table beneath that point, including streaming tables, materialized views and views (Beta). Unity Catalog treats views as tables, so FOR TABLES covers them too; "There is no separate FOR VIEWS or ON VIEW syntax." Databricks recommends "attaching policies at the highest applicable level, usually the catalog, to maximize governance efficiency."
**Principals (TO / EXCEPT).** TO names the users, groups or service principals the policy applies to. EXCEPT names principals who are exempt and see the data unfiltered and unmasked.
**Conditions (WHEN / MATCH COLUMNS).** WHEN decides which tables the policy applies to, using the built-in functions has_tag and has_tag_value. If you omit it, the condition defaults to TRUE. MATCH COLUMNS finds the target columns by their tags and gives each match an alias. "A policy can include up to 3 MATCH COLUMNS expressions, and all must match for the policy to apply."
Action. The action is ROW FILTER or COLUMN MASK, followed by the UDF that does the work.
Checkpoint 4 of 6· Match them up
Match each CREATE POLICY clause to its role
Tap a term, then the definition that fits it.
WHEN filters tables, MATCH COLUMNS selects columns, ON sets the attachment point, and TO/EXCEPT selects principals.
“WHEN condition: A boolean expression that determines which tables the policy applies to, based on their tags.”Source: docs.databricks.com
Checkpoint 5 of 6· Exam question
A Unity Catalog admin tags every column that stores a customer's government ID number with the governed tag `pii=true` across several schemas in the `finance` catalog. Security wants any column carrying that tag to be masked to show only the last four digits for everyone except the `compliance_officers` group, and wants newly created columns tagged the same way to be masked automatically without rewriting the policy. Which action meets this goal?
Correct answer: A — Create an ABAC column mask policy scoped to the catalog using `MATCH COLUMNS has_tag_value('pii','true') AS id_col ON COLUMN id_col`, so every matching column is masked automatically as it is tagged.
- A. A column-scoped ABAC policy built with `MATCH COLUMNS` and `has_tag_value('pii','true')` masks every column carrying that tag today and automatically covers any column tagged the same way afterward, which is exactly the catalog-wide, self-extending behavior requested.
- B. A manually attached masking UDF via `ALTER TABLE ... ALTER COLUMN ... SET MASK` only covers the specific column it was applied to, so the admin would have to repeat the same statement by hand for every newly tagged column instead of it happening automatically.
- C. A view-based workaround only reshapes the query surface for whoever queries the view; it does not stop anyone from bypassing the mask by querying the base table directly, and it still needs to be rebuilt for each new table.
- D. Building narrower per-group views that drop the ID column entirely removes the field for those groups instead of masking it, and it still requires a new view definition each time a column is newly tagged, so it does not scale automatically.
4.ABAC policies vs table-level row filters and column masks
ABAC does not replace table-level row filters and column masks. The two approaches suit different situations, and Databricks gives guidance on when to use each.
| Situation | Better fit |
|---|---|
| Consistent access rules needed across many tables, schemas, or catalogs | ABAC policy |
| Policy authors define rules while data stewards classify data with tags | ABAC policy |
| Growing estate where new tables should be covered once tagged | ABAC policy |
| Each table has strict, specific logic that doesn't generalize | Table-level row filter or column mask |
| Small, stable set of tables managed by their own owners | Table-level row filter or column mask |
Both kinds can exist on the same table, but at query time only one distinct row filter can apply to a table, and only one distinct column mask can resolve per column. "Databricks evaluates conflict by comparing the functions applied, not the data output." If an ABAC policy and a table-level filter use the same function for the same user, the query runs. If they use different functions, access is blocked.
Checkpoint 6 of 6· Check yourself
The orders table has a manually applied row filter f_region. A catalog-level ABAC policy applies a different function, f_region_v2, to the same user. Both functions return exactly the same rows. What happens when that user queries orders?
Databricks detects conflicts by comparing which functions are applied, not what they return, so two different functions always conflict.
“If they apply different functions, Databricks blocks access and returns an error”Source: docs.databricks.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Tagging a table or catalog
piimeans its columns are treated as PII by MATCH COLUMNS conditions.Why is that wrong?Columns do not inherit tags from their table, schema or catalog. Column tags must be applied directly, either by hand or by Data Classification.
2.A table-level filter and an ABAC filter don't conflict as long as they return the same rows.Why is that wrong?
Conflict is judged by the function applied. Two different functions for the same user block access even when their output is identical.
Covered in ABAC policies vs table-level row filters and column masks
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“uses governed tags and policies to grant permissions based on object attributes rather than per-object grants”
↩︎ From per-table rules to tag-driven policies“Governed tags are key-value pairs defined at the account level and applied to Unity Catalog securable objects”
↩︎ Governed tags: the attributes policies match on“Databricks recommends attaching policies at the highest applicable level, usually the catalog, to maximize governance efficiency.”
↩︎ Anatomy of a policy: scope, principals, conditions, action“This allows a single policy to apply automatically across multiple data objects that meet its conditions.”
↩︎ Key concept“column tags do not inherit from the parent table and must be applied directly”
↩︎ Exam trap 1“As new data objects are created and tagged, the policy applies automatically without requiring separate policy definitions for each object.”
↩︎ Prediction“Row filter and column mask policies require UDFs to implement the filtering or masking logic.”
↩︎ Checkpoint - 2.
“only users with the ASSIGN privilege on the department governed tag can assign or modify department tag values.”
↩︎ Governed tags: the attributes policies match on - 3.
“A family of system tags that Databricks Data Classification automatically applies to columns containing PII or other sensitive data.”
↩︎ Governed tags: the attributes policies match on“All objects within a catalog or schema automatically inherit governed tags that you apply to that catalog or schema, except individual table columns.”
↩︎ Checkpoint - 4.
“A policy can include up to 3 MATCH COLUMNS expressions, and all must match for the policy to apply.”
↩︎ Anatomy of a policy: scope, principals, conditions, action“There is no separate FOR VIEWS or ON VIEW syntax.”
↩︎ Anatomy of a policy: scope, principals, conditions, action“WHEN condition: A boolean expression that determines which tables the policy applies to, based on their tags.”
↩︎ Checkpoint - 5.
“Your data estate is growing and you want new tables covered automatically when they are tagged.”
↩︎ ABAC policies vs table-level row filters and column masks“Databricks evaluates conflict by comparing the functions applied, not the data output.”
↩︎ Exam trap 2“If they apply different functions, Databricks blocks access and returns an error”
↩︎ Checkpoint - 6.https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac/policy-evaluationOfficial docs
“Only one distinct row filter can be applied at query time for a given table and user.”
↩︎ ABAC policies vs table-level row filters and column masks