Build

Unity Catalog grants

Build2 min readreview needed

Terraform: plural vs singular#

We moved catalog and schema grants from databricks_grants (plural) to databricks_grant (singular) because the plural form is authoritative — it owns all grants on the object and removes anything it doesn't define. DABs sets its own grants on catalogs and schemas when deploying jobs and pipelines, so Terraform was wiping those out on every apply. The singular form manages one principal at a time, so Terraform and DABs can coexist without stepping on each other. External locations still use the plural form because we verified through the API that only Terraform's service principal has ever created or granted permissions on them, so there's no conflict.

The privilege model#

The rules underneath those Terraform resources. Source: the databricks-unity-catalog agent skill, references/1-access-control.md. See skills-watch.md for the install command.

  • Data access needs traversal. SELECT on a table is not enough. The principal also needs USE CATALOG on the catalog and USE SCHEMA on the schema. A missing traversal privilege is the most common cause of PERMISSION_DENIED on a table you already granted.
  • BROWSE shows metadata only. A principal with BROWSE sees the object in the explorer and still cannot read it. Grant the action privilege as well.
  • Inheritance covers future children. GRANT SELECT ON SCHEMA reaches every table in that schema, including tables created later. A table-level grant does not.
  • There is no DENY. Absence of a grant is the deny. To lock down one child while a broad parent grant exists, you must narrow the parent grant. A REVOKE on the child does nothing.
  • MANAGE delegates grant administration on a securable without transferring ownership.
  • Own with groups, not people. Access breaks when an individual owner leaves. Use ALTER … OWNER TO a group.
  • Account groups, not workspace-local groups. A grant to a workspace-local group looks applied and has no effect. is_account_group_member('grp') confirms membership.

List the visible direct and inherited table grants:

SELECT grantee, privilege_type, inherited_from
FROM system.information_schema.table_privileges
WHERE table_catalog = 'analytics'
  AND table_schema = 'gold'
  AND table_name = 'customers'
ORDER BY grantee;

This query returns principals, not the users inside each group. It can also omit grants when the caller has MANAGE but does not own the object. Use SHOW GRANTS or Catalog Explorer when you need the complete object grant list.

Row filters and column masks layer on top of these grants and never replace them. See governance-pii-abac.md, which covers the ABAC CREATE POLICY form of the same controls.

Source: https://learn.microsoft.com/azure/databricks/sql/language-manual/information-schema/table_privileges