Unity Catalog & Governance
The governance layer every Databricks conversation eventually reaches - and one Saikrishna works with daily in ADM's production finance and HR estates.
Why Unity Catalog exists
Before Unity Catalog (UC), every Databricks workspace shipped with its own Hive metastore. That meant governance was fractured exactly along workspace boundaries: a table defined in the dev workspace did not exist in prod, permissions were managed per workspace with legacy table ACLs (or worse, with raw cloud storage IAM), there was no built-in lineage, and audit logs told you what clusters did, not who touched which column. Multiply that by five workspaces and three environments and you get the classic enterprise mess: nobody can answer "who can read salary data, and who actually did last Tuesday?"
UC fixes this by centralizing governance at the account level. One metastore per cloud region governs every workspace attached to it. Identities come from the account (synced from Entra ID / your IdP via SCIM), privileges are ANSI-style GRANTs stored once and enforced everywhere, and every access is logged and lineage-tracked automatically. On the Data Intelligence Platform, UC is no longer optional plumbing - it is the substrate for tables, files, models, functions, dashboards, Genie spaces, and serving endpoints alike.
The object model and the three-level namespace
UC organizes everything in a strict hierarchy. Get this picture solid - interviewers probe it casually ("where does a volume live?") to see if you have actually worked with it:
Metastore (one per region, account-level)
└── Catalog e.g. fin_prod
└── Schema (database) e.g. r2r_gold
├── Tables managed or external (Delta, and now managed Iceberg)
├── Views standard + materialized; dynamic views for filtering
├── Volumes governed file storage (managed or external)
├── Functions SQL/Python UDFs - also usable as AI agent tools
└── Models MLflow registered models live here too
Every securable is addressed with the three-level namespace: catalog.schema.object. So fin_prod.r2r_gold.pl_actuals, not the two-level database.table of the Hive world. The legacy metastore still appears as a catalog literally named hive_metastore, which is the bridge you walk across during migration.
Sitting beside the data hierarchy are the objects that connect UC to cloud storage:
- Storage credential - wraps a cloud identity (on Azure, a managed identity via the Databricks access connector) that UC uses to reach ADLS/S3/GCS. Users never hold the storage keys.
- External location - a storage path plus a storage credential, itself a securable. Granting
CREATE EXTERNAL TABLEon an external location is how you delegate "you may create tables under this container path" without handing out the credential. - Connections - power Lakehouse Federation, so you can register and query external systems (SQL Server, Snowflake, PostgreSQL, etc.) as foreign catalogs under UC governance.
Catalogs are your coarsest isolation tool. A common enterprise pattern is catalog-per-environment-per-domain (fin_dev, fin_qa, fin_prod), with catalog-workspace bindings so the prod catalog is only even visible from the prod workspace - a natural fit for a finance domain like the R2R analytics estate Saikrishna leads.
The privilege model: GRANT, ownership, inheritance
UC privileges are ANSI-SQL style: GRANT / REVOKE on a securable, to a principal (user, group, or service principal - always prefer groups). Three rules carry most of the weight:
- Inheritance flows downward. A grant on a catalog applies to every schema and object inside it; a grant on a schema covers its tables, views, volumes, and functions. Grant broad-read at the catalog level, restrict by exception below.
- Access requires the full chain. To query a table you need
SELECTon the table andUSE SCHEMAon its schema andUSE CATALOGon its catalog. ForgettingUSE CATALOGis the number-one "why can't this group see anything?" ticket. - Owners are special. Every object has an owner (ideally a group, not a person) who can do anything to it, including granting.
ALL PRIVILEGESexists but explicit grants read better in an audit.
| Privilege | Applies to | What it allows |
|---|---|---|
USE CATALOG / USE SCHEMA | Catalog / schema | Traverse the namespace; prerequisite for everything below |
SELECT | Table, view | Read rows |
MODIFY | Table | INSERT, UPDATE, DELETE, MERGE |
CREATE TABLE / CREATE SCHEMA | Schema / catalog | Create child objects |
READ VOLUME / WRITE VOLUME | Volume | Read or write files through the volume path |
EXECUTE | Function, model | Invoke a UDF or registered model |
CREATE EXTERNAL TABLE | External location | Create external tables under that path |
BROWSE | Catalog and below | See metadata in Catalog Explorer without reading data |
ALL PRIVILEGES | Any securable | Everything; use sparingly |
GRANT USE CATALOG ON CATALOG fin_prod TO `grp-finance-analysts`;
GRANT USE SCHEMA, SELECT ON SCHEMA fin_prod.r2r_gold TO `grp-finance-analysts`;
REVOKE SELECT ON TABLE fin_prod.r2r_gold.pl_actuals FROM `grp-contractors`;
SHOW GRANTS ON SCHEMA fin_prod.r2r_gold;
Managed vs external - tables and volumes
Same Delta files either way; the difference is who controls the storage location and lifecycle.
| Managed | External | |
|---|---|---|
| Storage path | UC-controlled location (metastore, catalog, or schema level); you never reference the path | A path you register under an external location |
| DROP TABLE | Deletes metadata and data (after a grace window) | Deletes metadata only; files stay in storage |
| Optimizations | Full predictive optimization: auto OPTIMIZE / VACUUM / ANALYZE (default for accounts created on/after Nov 11, 2024) | You own maintenance jobs yourself |
| Formats | Delta, plus managed Apache Iceberg tables (GA, read/write via UC's Iceberg REST Catalog) | Delta, Parquet, CSV, JSON, etc. |
| When to choose | Default for everything new - Databricks' clear recommendation | Data shared with non-Databricks writers, contractual storage placement, lift-and-shift of existing paths |
Volumes follow the same split and exist to kill direct-path file access: instead of mounting storage or pasting abfss:// URIs into notebooks, you read and write files under /Volumes/catalog/schema/volume/... and UC enforces READ VOLUME / WRITE VOLUME. Landing zones for raw files, configs, and ML artifacts all belong in volumes now; DBFS mounts are legacy.
Pitfall: "external tables for governance" is dated advice. At Maersk, Saikrishna's team deliberately moved managed Hive-era tables to external tables for governance and cost control - the right call then, because dropping a managed Hive table destroyed data and the storage was opaque. Under UC the calculus has inverted: managed tables get predictive optimization, faster reads, and clean lifecycle handling, so Databricks now recommends managed for new tables. If you tell an interviewer "we always use external tables for control," you are signaling pre-UC habits. Tell the evolution story instead - it shows you track the platform.
Row filters and column masks
Fine-grained access control attaches directly to the table, so it is enforced no matter which client queries it - SQL warehouse, notebook, dashboard, or a Genie space.
- A row filter is a SQL UDF returning BOOLEAN, bound to a table; rows where it returns false silently disappear for non-qualifying users.
- A column mask is a UDF bound to a column that rewrites the value at query time - return the real value for privileged groups, a redaction for everyone else.
-- Row filter: HR sees everything, business partners only their region
CREATE OR REPLACE FUNCTION hr_prod.gov.region_filter(region STRING)
RETURN is_account_group_member('grp-hr-admins')
OR exists(
SELECT 1 FROM hr_prod.gov.user_region_map m
WHERE m.user_name = current_user() AND m.region = region
);
ALTER TABLE hr_prod.gold.headcount_salaries
SET ROW FILTER hr_prod.gov.region_filter ON (region);
-- Column mask: salary visible only to compensation admins
CREATE OR REPLACE FUNCTION hr_prod.gov.mask_salary(salary DECIMAL(12,2))
RETURN CASE WHEN is_account_group_member('grp-hr-comp-admins')
THEN salary ELSE NULL END;
ALTER TABLE hr_prod.gold.headcount_salaries
ALTER COLUMN salary SET MASK hr_prod.gov.mask_salary;
Older alternative: dynamic views with is_account_group_member() in the view body. They still work and remain useful when the logic must combine masking with joins or aggregation, but filters and masks are preferred because they protect the base table itself - no way to route around them by querying the table directly. Also know the newer ABAC direction: governed tags plus tag-driven policies, so one policy ("mask anything tagged pii.salary") covers many tables - in preview as of mid-2026, so hedge accordingly.
This is not theory for him. ADM's three production GenAI agents over HR data (PeopleSoft + SAP labor) - the Genie-based Corporate Headcount & Salaries Data Agent, the Policy RAG Assistant on Vector Search, and the multi-agent router, all served as a Databricks App with a Streamlit UI - sit on top of UC row- and column-level permissions for HR users. Salary data is the textbook sensitive column. Because Genie generates SQL that executes under the asking user's identity, the UC filters and masks are what guarantee an HR user can only ever see what they are entitled to - the LLM cannot leak rows it cannot read. That one sentence ("we enforced governance below the agent, not in the prompt") lands extremely well in interviews.
"How would you secure sensitive data, like salaries, in a lakehouse that feeds both BI and a GenAI assistant?" Outline: (1) coarse access via catalog/schema GRANTs to groups synced from the IdP; (2) row filters for region/population scoping and column masks for the salary column, attached to the gold table so enforcement is client-independent; (3) execution as the requesting user (Genie runs its generated SQL with the asking user's credentials; on clusters, dedicated access mode - formerly "single user") so filters and masks apply per person; (4) audit via system tables to prove who saw what; (5) the warning that prompt-level guardrails are UX, not security - governance must live in UC. Then anchor it with the ADM HR agents story above.
Lineage - and why auditors love it
UC captures lineage automatically from every query that runs on UC-enabled compute: table-level (this gold table is fed by these silver tables) and column-level (this KPI column derives from these source columns), across SQL, Python, Scala, and R, and extending to notebooks, jobs, and dashboards that touched the data. No agents to install, no third-party scanner to reconcile - it falls out of query execution. You can browse it in Catalog Explorer or query it programmatically via the lineage system tables.
Why auditors care: lineage turns "trust me, that P&L number comes from SAP" into a clickable, queryable evidence trail - source column to transformation to executive dashboard. Impact analysis works in reverse: before you change a silver table, lineage tells you every downstream consumer you are about to break.
At ADM, Saikrishna leads Finance Record-to-Report analytics end to end: Bronze/Silver/Gold medallion pipelines on Azure Databricks + ADF integrating JDE, SAP, HFM (Hyperion), IBM DB2, and IBM APGO Web Wire into Delta Lake, with lineage and Unity Catalog governance built in. The consumers are Executive Committee and CFO-level KPI frameworks - P&L, Budget vs Actual, Expense Forecasting, Capital Allocation. For Finance and Audit stakeholders, the ability to trace a number on an executive dashboard back through gold and silver to the exact source-system column is precisely what closes the review conversation. That is the lineage story: not a feature checkbox, but how a finance platform earns trust.
System tables: observability and FinOps in SQL
The system catalog exposes platform telemetry as Delta tables you simply query - once an admin enables the schemas and grants access:
system.access.audit- who did what: grants, logins, table reads, permission changes. Your audit evidence and anomaly-detection feed.system.billing.usage+system.billing.list_prices- DBU consumption by SKU, workspace, and tags. This is the FinOps backbone: join usage to custom tags and you get cost-per-team or cost-per-pipeline dashboards without exporting anything to a spreadsheet.system.access.table_lineage/column_lineage- lineage as data, for programmatic impact analysis.system.lakeflow.*- job and run telemetry for reliability reporting.
-- Top DBU consumers, last 30 days, by cost-center tag
SELECT u.custom_tags['cost_center'] AS cost_center,
u.sku_name,
SUM(u.usage_quantity) AS dbus
FROM system.billing.usage u
WHERE u.usage_date >= current_date() - INTERVAL 30 DAYS
GROUP BY 1, 2
ORDER BY dbus DESC;
Tie this to FinOps work you have actually done: ADM cluster right-sizing, autoscaling policies, and Delta tuning all need a measurement loop, and system tables are the native one. "I'd put an AI/BI dashboard on system.billing.usage grouped by job tag, then re-check after each right-sizing change" is a concrete, current answer. Note retention limits (audit is finite - export long-term if compliance needs years) and that system tables are read-only.
Delta Sharing
Delta Sharing is the open protocol for sharing live data without copying it. Two flavors to keep straight:
- Open sharing - the recipient is anyone with a Delta Sharing client (pandas, Spark, Power BI, Tableau); they authenticate with a token-bearing credential file. No Databricks required on their side. Read-only tables and volumes.
- Databricks-to-Databricks - both sides have UC; the share attaches as a catalog in the recipient's metastore. Richer: notebooks, views with masks intact, models, and governance stays attached. Cross-cloud and cross-region works.
The provider creates a SHARE (a named collection of objects), a RECIPIENT, and grants the share to the recipient - all auditable UC objects. This also underpins the Databricks Marketplace and Clean Rooms. For Saikrishna this is study knowledge, not a production claim - his sharing surface at ADM has been Power BI and Databricks Apps - but it is a reliable interview topic because it differentiates "copy the data over SFTP" thinking from lakehouse-native thinking.
Governing ML and AI assets
UC's quiet superpower is that the same model governs non-tabular assets:
- Models - MLflow models register into UC (
catalog.schema.model) with versioning and aliases like@champion;EXECUTEgoverns invocation, and lineage links a model version to its training tables. - Functions - SQL/Python UDFs in UC double as governed agent tools: a Genie space or Agent Bricks agent can only call functions its identity is allowed to execute.
- Vector Search indexes and serving endpoints - also UC-governed, which is why the ADM Policy RAG assistant's retrieval layer inherits the same access discipline as its tables. The newer Unity AI Gateway (Beta as of mid-2026) extends this control plane to LLM endpoints and agents.
Migrating from hive_metastore
High-level playbook an interviewer expects you to sketch:
- Inventory the legacy metastore - tables, formats, mounts, who reads what (UCX, the Databricks Labs toolkit, automates assessment).
- External tables: register the storage as external locations, then
SYNC SCHEMA/SYNC TABLEto upsert UC entries pointing at the same files - metadata-only, repeatable, cheap. - Managed Hive tables:
CREATE TABLE AS SELECTor deep clone into UC managed tables (data copy, but you land on predictive-optimization-eligible storage). - Repoint and govern: update jobs and views to three-level names, replace mounts with volumes, recreate ACLs as UC grants to groups, then lock down direct storage access so UC is the only door.
- Decommission in waves - run dual-read for a sprint, watch audit/lineage system tables to confirm nothing still reads the old paths.
"Walk me through migrating a workspace from the Hive metastore to Unity Catalog. What breaks?" Strong outline: assessment with UCX; SYNC for external tables vs CTAS/clone for managed; the things that actually break - two-level table references in old code, dbfs:/mnt paths (replace with volumes), init scripts and cluster-scoped credentials, and jobs running on clusters without UC-capable access modes (standard/dedicated; the old no-isolation mode cannot see UC data). Close with sequencing: migrate readers before writers, keep hive_metastore readable during transition, verify with lineage that the legacy side has gone quiet before dropping it.
What's new as of mid-2026
- Metric views are GA - business metrics (measures, dimensions, joins) defined once in UC and queried consistently from SQL, AI/BI dashboards, and Genie; materialization of metric views is still Experimental. For someone who has built KPI frameworks for CFO-level consumers, this is the feature to name-drop: it moves metric definitions out of per-dashboard logic into governed objects.
- Managed Apache Iceberg tables are GA - full read/write through UC's Iceberg REST Catalog, alongside UniForm (Delta tables readable, read-only, by Iceberg clients). UC is positioning as the neutral catalog over both formats; Iceberg v3 brings deletion vectors, row tracking, and VARIANT.
- Unity AI Gateway (Beta) - the governance control plane extending UC-style policy to LLM endpoints, agents, and MCP servers; the legacy Mosaic AI Gateway features persist on serving endpoints. Naming is in flux - check current docs before quoting it in an interview.
Common trap: claiming UC "encrypts" or "secures the storage layer" by itself. UC governs access through Databricks compute and APIs. If users or service principals retain direct IAM access to the underlying ADLS containers, they can bypass every GRANT, filter, and mask you wrote. A complete answer always ends with: lock down the storage accounts so the UC storage credential is effectively the only identity with data-plane access, and treat any direct-path access as an exception to be audited away.
Where to next: governance shapes how you model data in the first place - catalog and schema layout per layer is half of medallion design. Continue to Lakehouse Data Modeling, or revisit how the tables themselves work in Delta Lake Internals.