The Essentials
Unity Catalog ABAC controls access by tag instead of by table. You classify sensitive data, apply governed tags to columns and tables, then write one row filter or column mask policy on a catalog or schema that applies to every tagged object beneath it. Build it in four steps: classify, tag, write the policy, and test against a known-bad case.
- Status: ABAC row filter and column mask policies, governed tags and data classification have been generally available since 13 May 2026.
- Cost: no separate licence; the work is designing a tag vocabulary and writing a handful of SQL functions.
- Effort: a first domain takes days, most of it spent agreeing what each tag means.
- Risk: an untagged sensitive column is unprotected, so tagging coverage becomes your control.
Table-by-table grants work until the catalog grows. Then every new table is a new access decision, every masked column needs its own function attached by hand, and the review becomes a spreadsheet of hundreds of grants that nobody reads to the end.
Attribute-based access control flips that. On 13 May 2026, Databricks announced general availability of ABAC policies for row filtering and column masking, governed tags and automated data classification in Unity Catalog. The access decision moves from the table to the attribute: if a column is tagged as a social security number, it is masked for everyone outside HR, wherever it lands in the lakehouse.
The hard part is not the syntax. It is the order of operations and the discipline to prove a policy blocks what it should. Below is the build order we use, with syntax checked against current Databricks documentation.
What Exactly Is Unity Catalog ABAC?
In the Databricks documentation, ABAC determines access by evaluating attributes on securable objects, and those attributes are governed tags. A policy attaches at a level of the hierarchy (catalog, schema or table) and evaluates every object beneath it at query time. Add a table to the schema, tag one column, and the policy already covers it.
The documentation also describes GRANT policies and DENY policies, with DENY still in Beta, and metastore-level policies in Beta too. This article sticks to row filter and column mask policies at catalog, schema and table level, which is the part the May announcement made generally available. If you are still moving workspaces onto Unity Catalog, finish that first; our Unity Catalog migration guide covers the sequence, because ABAC only protects what the catalog governs.
How Does ABAC Differ From Table-Level Filters and Grants?
| Approach | Where the rule lives | What happens when a new table arrives | What a reviewer reads | Best used for |
|---|---|---|---|---|
| Object grants | On each catalog, schema or table | Inherits grants from its parent; no column or row protection | Grant list per group | Coarse access: who can see a schema at all |
| Table-level row filter or column mask | A function attached to one table or column | Unprotected until someone attaches the function | Every table’s filters, one by one | A single table with a unique rule |
| ABAC policy | On a catalog or schema, matched by tags | Protected as soon as the sensitive column is tagged | A short list of policies plus tag coverage | The same rule across many tables |
On a lakehouse, grants still decide whether a group can reach a schema. ABAC decides which rows and column values that group sees once it gets there. You need both.
Step 1: How Do You Classify Data Before Tagging It?
Classification is a business decision before it is a platform feature. Write down the categories you will protect and what each one triggers. Automated data classification, part of the May release, helps you find candidate sensitive columns across the catalog, but someone with domain knowledge still confirms each one. A model that flags a column called notes as free text does not know whether your support team pastes card numbers into it.
Keep the vocabulary small. Four to six tag keys with a few allowed values each will carry most mid-market estates.
| Tag key | Allowed values | Applied to | Who may assign it | What policy it drives |
|---|---|---|---|---|
| pii | ssn, email, phone, address, dob | Columns | Data stewards | Column mask for non-HR and non-support groups |
| sensitivity | public, internal, confidential, restricted | Tables | Domain owners | Which tables a row filter policy targets |
| geo_region | (no values; marks the region column) | Columns | Data engineers | Row filter by region for regional teams |
| payment | pan, bank_account | Columns | Security lead | Full mask for everyone outside finance |
Note the underscore in geo_region. According to the tags documentation, tag keys cannot contain periods, commas, hyphens, equals signs, slashes or colons, and keys are case-sensitive, so “PII” and “pii” are different tags. Decide the casing once.
Step 2: How Do You Set Governed Tags?
A governed tag is an account-level tag whose allowed keys and values are fixed by a tag policy. Only principals with the ASSIGN permission on that tag can apply it. That permission is the real control: if anyone can tag or untag a column, anyone can switch off a mask.
Create the governed tags in the account, grant ASSIGN to the steward groups from your table, then apply them. On a column, the documented syntax is:
ALTER TABLE finance.customers.profiles ALTER COLUMN ssn SET TAGS ('pii' = 'ssn');
On Databricks Runtime 16.1 and above there is also a SET TAG ON form for securables such as catalogs. Mind the limits: 50 tags per securable object and 1,000 column tags per table.
Step 3: How Do You Write the Row Filter and Column Mask Policies?
Each policy calls a SQL function in Unity Catalog. The function holds the logic; the policy decides where it applies and to whom. Policy creation needs Databricks Runtime 16.4 or above, or serverless compute, and the MANAGE privilege on the securable or ownership of it, per the policy documentation.
A column mask that shows only the last four digits of any column tagged ssn, adapted from the CREATE POLICY reference:
CREATE FUNCTION ssn_to_last_nr (ssn STRING, nr INT) RETURNS STRING RETURN right(ssn, nr);
CREATE POLICY ssn_mask ON CATALOG employees COLUMN MASK ssn_to_last_nr TO all_staff EXCEPT hr_admins FOR TABLES MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn ON COLUMN ssn USING COLUMNS (4);
A row filter that hides EU customers from analysts on any restricted table in a schema:
CREATE FUNCTION non_eu_region (geo_region STRING) RETURNS BOOLEAN RETURN geo_region <> 'eu';
CREATE POLICY hide_eu_customers ON SCHEMA prod.customers ROW FILTER non_eu_region TO analysts FOR TABLES WHEN has_tag_value('sensitivity', 'restricted') MATCH COLUMNS has_tag('geo_region') AS region USING COLUMNS (region);
Read the clauses in order. ON sets the scope. TO and EXCEPT set the principals, so put exceptions on a group, never a person. WHEN chooses which tables the policy targets by their tags. MATCH COLUMNS finds the columns by tag, with up to three expressions, and USING COLUMNS passes them, or a constant such as 4, to the function.
Step 4: How Do You Test a Policy Against a Known-Bad Case?
This is the step teams skip, and it is the one an auditor cares about. A policy that returns the right rows for an authorised user proves nothing. You need a test that would fail if the policy were missing.
- Build a canary table. In a test schema under the same policy scope, create a small table with a fake SSN column and rows from an EU and a non-EU region. Tag it exactly as production would be tagged.
- Query as a principal who should be blocked. Use a test service principal in the analysts group. The SSN must come back masked and the EU rows must be absent.
- Query as a principal in the exception group. The same query must return the full value. If both principals see the same thing, the policy is not doing what you think.
- Remove the tag and query again. The value should now appear unmasked. That proves the tag drives the protection, and it shows your team exactly what an untagged column costs.
- Check the effective policies.
SHOW EFFECTIVE POLICIESlists the policies from parent scopes that apply to an object, which catches a policy attached at the wrong level.
Schedule steps 2 to 4 as a job and fail it loudly when a result changes. In Lean terms that is a control plan: the check runs whether anyone remembers it or not. The audit log system table, in Public Preview with 365-day default retention, records policy and permission changes, so a failed test can be traced to the change behind it.
What Goes Wrong in an ABAC Rollout?
The most common failure is treating ABAC as finished once the policies exist. The policies are only as good as the tags, and tags drift. A new pipeline lands a table with an email_address column that nobody tagged, and it is readable in full by every analyst until the next classification pass. Make tagging part of the release checklist for every new table, and report untagged columns that classification flags as sensitive every week.
The second failure is exceptions granted to people. An EXCEPT clause naming one manager outlives that manager’s role. Put every exception on a group with an owner and a review date. Third, teams leave service principals out of the TO clause because “the pipeline needs full access.” Pipelines that write need the data; AI agents and reporting jobs that only read usually do not, and they are often the largest readers on the platform. Finally, watch for overlap: two policies matching the same column produce results that are hard to reason about. Keep one policy per tag and scope, and document which team owns it. A lakehouse with ten clear policies is easier to defend than one with forty overlapping ones.
What Should You Build First This Quarter, and in What Order?
- Weeks 1 and 2: agree the tag vocabulary with domain owners and security, create the governed tags, and grant ASSIGN only to steward groups.
- Weeks 3 and 4: run automated classification on one high-value domain, confirm the candidates, and tag them.
- Weeks 5 and 6: write one column mask and one row filter policy for that domain and build the canary test job.
- Weeks 7 to 10: retire the table-level filters and masking views the new policies replace, one table at a time, re-running the canary each time.
- Weeks 11 and 12: extend to the next domain, and add tag coverage and test results to the quarterly access review.
Our Unity Catalog guide covers the governance model this sits on. If you want the build done with you, our Databricks consulting work starts with the tag vocabulary, because that is where most lakehouse access designs go wrong.
Frequently Asked Questions (FAQs)
When did Unity Catalog ABAC become generally available?
Databricks announced general availability of ABAC row filter and column mask policies, governed tags and automated data classification on 13 May 2026. DENY policies and metastore-level policies were still described as Beta in the documentation.
What compute does Unity Catalog ABAC require?
The policy documentation lists Databricks Runtime 16.4 or above, or serverless compute. Confirm the current requirement in the documentation before rollout and plan cluster upgrades early.
What is the difference between a tag and a governed tag?
A governed tag is defined at the account level with a tag policy that fixes its allowed values, and only principals with the ASSIGN permission can apply it. That makes it safe to drive access policies from.
Can ABAC replace dynamic views for masking?
For many cases, yes. A policy protects the base table wherever it is queried, while a masking view only protects users who go through the view. Replace views gradually and test each table as you go.
Who can create an ABAC policy?
A principal with the MANAGE privilege on the catalog, schema or table, or the object’s owner. Keep that privilege with the platform or security team rather than with every domain team.

