Databricks DE ยท Topic 8.4

Attribute-Based Access Control (ABAC)

Govern by attribute, not by table: tag data with governed tags, write one CREATE POLICY targeting the tag, and it applies automatically โ€” cascading through the catalog hierarchy. This deep dive walks the verified policy DDL.

governed tagsCREATE POLICYhas_tag_valuecascades

The one-liner

ABAC = governed tags on data + policies (CREATE POLICY โ€ฆ ROW FILTER / COLUMN MASK) that target a tag via has_tag_value() and attach at catalog/schema/table level, applying automatically to any matching object. Define once, enforce everywhere.
๐Ÿท๏ธ Analogy: instead of locking each cabinet (per-table masks from 8.3), you put a "CONFIDENTIAL" sticker on documents and write one rule: "mask anything tagged CONFIDENTIAL." Tag a new doc โ†’ the rule covers it instantly.
โš ๏ธ ABAC DDL is evolving โ€” row-filter/column-mask policies are the core offering; GRANT policies are Beta. Verify current status in the docs.

Tag a column โ†’ the policy fires automatically

โ–ธ click "tag pii" on a column; the catalog policy masks it

ABAC policy on CATALOG prod:  mask columns tagged pii unless user โˆˆ pii_readers
๐Ÿ“ catalog prod  (policy attached)
๐Ÿ“‚ schema sales
๐Ÿ“„ customers.name visibletag pii
๐Ÿ“„ customers.ssn visibletag pii
๐Ÿ“„ customers.email visibletag pii
Nothing tagged yet โ†’ nothing masked.

1 ยท Governed tags (the attributes)

Governed tags are defined at the account level with access controls (unlike ad-hoc ungoverned tags). ABAC matches on governed tags; apply them to schemas/tables/columns:

ALTER TABLE prod.sales.customers ALTER COLUMN ssn     SET TAGS ('pii' = 'ssn');
ALTER TABLE prod.sales.customers ALTER COLUMN address SET TAGS ('pii' = 'address');

2 ยท Column-mask policy (mask any tagged column)

CREATE FUNCTION prod.sales.redact_ssn(s STRING) RETURNS STRING
  RETURN CASE WHEN is_account_group_member('pii_readers') THEN s ELSE '***-**-****' END;

CREATE POLICY redact_ssn_policy
  ON SCHEMA prod.sales
  COLUMN MASK prod.sales.redact_ssn
  TO `account users`
  FOR TABLES
  MATCH COLUMNS has_tag_value('pii', 'ssn') AS ssn_col
  ON COLUMN ssn_col;          -- every pii=ssn column in the schema is masked

3 ยท Row-filter policy (hide rows by tag)

CREATE POLICY hide_eu_customers
  ON SCHEMA prod.sales
  ROW FILTER prod.sales.is_not_eu_address
  TO `account users`
  FOR TABLES
  MATCH COLUMNS has_tag_value('pii', 'address') AS addr_col
  USING COLUMNS (addr_col);   -- the filter receives the tagged column

Match with has_tag('key') / has_tag_value('key','value'), combinable with AND/OR/NOT. Scope ON CATALOG, ON SCHEMA, or ON TABLE; a higher-level policy cascades to current & future matching objects.

4 ยท ABAC vs per-table (8.3) โ€” click each

Per-table (8.3)
ABAC (8.4)
Per-table row filters / column masks.
  • Configure each table with ALTER TABLE
  • New table โ†’ configure again
  • Fine for a few tables; doesn't scale
ABAC โ€” by tag, hierarchical.
  • Define a policy once, targeting a tag
  • Attach at catalog/schema โ†’ cascades to matching objects
  • Tag a new column โ†’ auto-covered
Per-tableABAC
Definedon each tableonce, by tag
New table/columnconfigure againauto-covered if tagged
Best fora few tablesenterprise-wide

Why it matters

๐Ÿข Real-world use case: tag every PII column pii and set one column-mask policy on the prod catalog โ€” every current and future pii-tagged column is masked automatically, no per-table work.

Uses, edge cases & limitations

Common gotchas