<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Row level Data  MASKING on multiple tables in Data Governance</title>
    <link>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173342#M3051</link>
    <description>&lt;DIV class=""&gt;&lt;DIV&gt;The recommended approach for applying filtering and masking consistently across large numbers of tables is &lt;STRONG&gt;Attribute Based Access Control&lt;/STRONG&gt; (ABAC) combined with &lt;STRONG&gt;governed tags&lt;/STRONG&gt;. ABAC policies scale across catalogs and schemas and are defined by higher level admins, generally preventing table owners from overriding them. They are also evaluated more efficiently than per table UDFs. You can configure a single schema level policy (masking any column tagged pii = ssn) that automatically covers all 120 tables without having to write 120 separate ALTER TABLE SET MASK statements. Check the limitations &lt;A href="https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac/requirements#policy-quotas" target="_self"&gt;here&lt;/A&gt;&lt;/DIV&gt;&lt;BR /&gt;&lt;DIV&gt;On the query regarding whether to propagate the attribute or derive it through entitlement and reference tables, both patterns are supported but there are distinct performance trade offs. Using mapping tables inside policy UDFs such as EXISTS (SELECT 1 FROM map_table WHERE principal = session_user() AND attribute = row_value) is possible but use ABAC if feasible. If you must use external lookup tables, keep them small to trigger a broadcast hash join. Large lookup tables will force a slow shuffle join, and you should avoid complex joins or multi hop derivations inside UDFs. For high volume tables missing the masking key, propagating the governance attribute during the silver layer transformation is a good route for performance, while entitlement tables are fine if they are small and keyed on simple equality.&lt;/DIV&gt;&lt;BR /&gt;&lt;DIV&gt;If you are utilizing a medallion architecture with Spark Declarative Pipelines, the right fit is to embed the security attribute during the silver layer transformation by denormalizing it from wherever the relationship natively lives. From there, tag the sensitive columns with governed tags and enforce the rules using one or two schema level ABAC policies.&amp;nbsp;&lt;SPAN&gt;More details &lt;/SPAN&gt;&lt;A style="font-family: inherit; background-color: #ffffff;" href="https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac" target="_self"&gt;here&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
    <pubDate>Wed, 14 Oct 2026 17:59:07 GMT</pubDate>
    <dc:creator>balajij8</dc:creator>
    <dc:date>2026-10-14T17:59:07Z</dc:date>
    <item>
      <title>Row level Data  MASKING on multiple tables</title>
      <link>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173192#M3048</link>
      <description>&lt;DIV&gt;&lt;P&gt;Hi Community,&lt;/P&gt;&lt;P&gt;I'm looking for guidance on implementing &lt;STRONG&gt;row-level masking (RLM)&lt;/STRONG&gt; at scale in Databricks using Unity Catalog.&lt;/P&gt;&lt;P&gt;Our challenge is that we have schemas containing a large number of tables (for example, one schema contains approximately 120 tables). We would like to enforce a consistent masking policy based on a business identifier (e.g., Customer ID, Policy Number, Business Unit, Broker ID, etc.), where users can access the row but sensitive values are dynamically masked based on their entitlements.&lt;/P&gt;&lt;P&gt;The challenge is that not all tables contain the identifier required to determine the masking rule. Some tables contain the key directly, while others are lookup/reference tables or contain only related attributes.&lt;/P&gt;&lt;P&gt;A few questions:&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;What is the recommended approach for implementing row-level masking across a schema when the masking key is not present in every table?&lt;/LI&gt;&lt;LI&gt;Have others used entitlement, lookup, or reference tables to drive masking decisions in these scenarios?&lt;/LI&gt;&lt;LI&gt;Is there a scalable governance pattern for avoiding the need to create and maintain masking policies across 100+ tables?&lt;/LI&gt;&lt;LI&gt;How have you handled cases where the masking identifier exists only in a subset of tables and must be derived through relationships with other tables?&lt;/LI&gt;&lt;LI&gt;Are there any best practices using Unity Catalog masking policies, ABAC, governed views, or other governance features for this type of design?&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Performance Consideration:&lt;/STRONG&gt; Has anyone observed a significant performance impact when implementing row-level masking policies that rely on entitlement, lookup, or reference tables, particularly where the masking decision must be derived through joins rather than a security attribute being present on the target table?&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Our objective is to implement a maintainable, centrally governed masking solution that can be applied consistently across large numbers of tables without introducing excessive operational overhead.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Current thinking:&lt;/STRONG&gt; Use a central entitlement table to determine which users can view unmasked values. However, we are trying to understand whether Databricks would recommend:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Propagating the masking/security attribute into all tables requiring masking, or&lt;/LI&gt;&lt;LI&gt;Deriving masking decisions through centralized entitlement and reference tables.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;We're particularly interested in the governance, maintainability, scalability, and performance trade-offs of these approaches in large enterprise implementations.&lt;/P&gt;&lt;P&gt;Any patterns, lessons learned, or architectural recommendations would be greatly appreciated.&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;Christopher&lt;/P&gt;&lt;/DIV&gt;</description>
      <pubDate>Wed, 14 Oct 2026 09:22:25 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173192#M3048</guid>
      <dc:creator>ChristophIRE</dc:creator>
      <dc:date>2026-10-14T09:22:25Z</dc:date>
    </item>
    <item>
      <title>Re: Row level Data  MASKING on multiple tables</title>
      <link>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173206#M3049</link>
      <description>&lt;P&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/228199"&gt;@ChristophIRE&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is something I worked through recently on a similar use case: enforcing row-level security across multiple tables with a central entitlement model. For this scale, ABAC is the right primary governance pattern rather than maintaining individual masks/filters on 100+ tables.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;1. Masking key not present in every table&lt;/STRONG&gt;&lt;BR /&gt;Derive or materialise the security attribute in a governed serving layer, or use a governed view rather than making every policy discover it through complex joins inside the policy path. Keeps the policy logic simple and avoids runtime join overhead on every query.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;2. Entitlement/lookup tables driving the masking decision&lt;/STRONG&gt;&lt;BR /&gt;Yes, this is a documented Databricks pattern. A small entitlement/mapping table maps &lt;STRONG&gt;current_user&lt;/STRONG&gt;() to allowed business attributes or masking levels, and the policy UDF performs the lookup at query time. Keep the table small and the lookup logic simple, a single equality predicate on &lt;STRONG&gt;user_email&lt;/STRONG&gt; pushes cleanly to the parquet scan and stays Photon-native.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;One hard constraint worth knowing upfront:&lt;/EM&gt;&lt;/STRONG&gt; the entitlement/mapping table must remain free of row filters or column masks. Unity Catalog does not allow a table with an active policy to be read inside another table’s policy, you’ll hit UNSUPPORTED_NESTED_ROW_OR_COLUMN_ACCESS_POLICY. Protect the mapping table using normal UC privileges instead, users never need direct access to it, the UDF runs under the owner's rights to read the mapping table, while current_user() still resolves to the calling user for the row filter itself.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;3. Avoiding policy management on 100+ tables&lt;/STRONG&gt;&lt;BR /&gt;Use tag-based ABAC policies applied via governed tags in Catalog Explorer. The policy automatically applies to every table/column carrying that tag, including newly tagged objects added later, no ALTER TABLE on each table required.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;4. Identifier exists only in some tables&lt;/STRONG&gt;&lt;BR /&gt;Avoid deriving it through arbitrary business-table joins inside the policy path. Propagate a stable security attribute into the governed layer where practical. Lookup/reference tables with no entity-level security relationship may not require the same policy at all.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;5. ABAC vs masks vs views&lt;/STRONG&gt;&lt;BR /&gt;A scalable pattern:&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Governed Tags → Schema/Catalog ABAC → Policy UDF → Entitlement Mapping Table.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Use dynamic views where you need joins, transformations, or derived security attributes. Use table-level row filters/column masks for exceptions rather than as the primary mechanism across 100+ tables.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;6. Performance&lt;/STRONG&gt;&lt;BR /&gt;Row filters and column masks execute UDF logic at query time, so there is a runtime cost. A few observations from my own implementation on this pattern:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;SQL UDFs inline at planning time:&amp;nbsp;&lt;/STRONG&gt;Photon sees a native BroadcastHashJoin, no ColumnarToRow transition. A Python UDF doing the same lookup would fall back on every row via BatchEvalPython.&lt;/LI&gt;&lt;LI&gt;The &lt;STRONG&gt;per-user predicate&lt;/STRONG&gt; pushes to the parquet scan, so the broadcast payload stays small regardless of total table size.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Overhead scales with permitted access scope, not table row count&lt;/STRONG&gt;: Tested up to ~18B rows table. Users with narrow access on larger tables outperformed broad-access users on smaller ones due to file pruning&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Benchmark representative workloads:&lt;/STRONG&gt;&amp;nbsp;large entitlement tables or multi-table joins in the policy path will hurt performance noticeably&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;STRONG&gt;Recommendation&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Propagate/materialise the security attribute where practical and use a central entitlement table for authorisation. Reserve runtime joins to reference/business tables for cases where deriving the attribute beforehand is genuinely impractical. For 100+ tables, tag-based ABAC with a single central UDF is the only maintainable path at that scale.&lt;/P&gt;&lt;P&gt;Have covered this pattern and the scaling observations in more detail in another &lt;A href="https://community.databricks.com/t5/community-articles/row-level-security-when-the-filter-column-is-not-on-your-table/m-p/169545#M1593" target="_blank"&gt;community post&lt;/A&gt;&amp;nbsp;where I mentioned bit more around scaling and worth going through it.&lt;/P&gt;</description>
      <pubDate>Wed, 14 Oct 2026 10:28:42 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173206#M3049</guid>
      <dc:creator>data_pulse</dc:creator>
      <dc:date>2026-10-14T10:28:42Z</dc:date>
    </item>
    <item>
      <title>Re: Row level Data  MASKING on multiple tables</title>
      <link>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173216#M3050</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/228199"&gt;@ChristophIRE&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;For your scenario of 120+ tables in a schema, the Databricks &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/abac/core-concepts" target="_blank"&gt;documentation&lt;/A&gt; explicitly recommends ABAC over per-table row filters and column masks. The core idea is that you define policies at the&amp;nbsp;&lt;/SPAN&gt;catalog or schema level&lt;SPAN&gt;, and they apply automatically to any table whose columns carry the right&lt;/SPAN&gt;&lt;SPAN&gt;. You don't need to write or maintain a separate masking policy for each table. Refer to &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/abac/abac-vs-rls-cm" target="_blank"&gt;this.&lt;/A&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here is how it works...&amp;nbsp;You basically create governed tags at the account level (e.g., a&amp;nbsp;pii&amp;nbsp;tag with values like&amp;nbsp;ssn,&amp;nbsp;email,&amp;nbsp;name), then tag the sensitive columns across your tables. You write one ABAC policy scoped to your schema that uses&amp;nbsp;MATCH COLUMNS has_tag_value('pii', 'email')&amp;nbsp;to dynamically discover which columns to mask. When new tables are added and tagged, the policy applies automatically with no additional configuration.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Your main challenge, as I read it, is how to handle the tables when the masking key isn't there.&lt;SPAN&gt;&amp;nbsp;There are a few patterns to consider.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;For column masking (hiding PII values)....&amp;nbsp;ABAC's&amp;nbsp;MATCH COLUMNS&amp;nbsp;clause is something to explore. If a table doesn't have a column tagged&amp;nbsp;pii, the policy simply doesn't apply to that table, and no masking occurs. This is by design. You tag only the columns that actually contain sensitive data, and the policy targets them dynamically. Tables that are pure lookup/reference tables without PII columns are naturally excluded.&lt;/P&gt;
&lt;P&gt;For row filtering (restricting which rows a user can see)...&amp;nbsp;This is where things get more nuanced. If the business identifier needed to determine row-level access (e.g., Customer ID or Business Unit) isn't present in a given table, you have two realistic options:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV data-genai-markdown-block="true"&gt;Propagate the security attribute into the table.&amp;nbsp;Add the filtering key (e.g.,&amp;nbsp;business_unit) as a column to tables that need row-level filtering. This is the more performant option because the row filter UDF can reference the column directly without any joins. It also enables predicate pushdown, which matters at scale.&lt;BR /&gt;&lt;BR /&gt;&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV data-genai-markdown-block="true"&gt;Use a centralised entitlement/lookup table inside the UDF.&amp;nbsp;You can write a UDF that checks a small mapping table to determine whether the current user has access. The Databricks docs provide an &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/abac/mapping-tables" target="_blank"&gt;option&lt;/A&gt;, including support for conditional masking and even automatic access expiration.&amp;nbsp;&lt;/DIV&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Since you mentioned you are thinking about the entitlement pattern,&amp;nbsp;here's how it works with ABAC. You create a small entitlement table that maps users to the data they're allowed to see:&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;CREATE TABLE access_rules (
  principal VARCHAR(255),
  allowed_value VARCHAR(64)
);&lt;/LI-CODE&gt;
&lt;P&gt;Then your UDF checks this table using&amp;nbsp;session_user():&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;CREATE FUNCTION row_access_check(business_key STRING) RETURNS BOOLEAN
RETURN EXISTS (
  SELECT 1 FROM access_rules
  WHERE principal = session_user() AND allowed_value = business_key
);&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;You can then attach this as an ABAC row filter policy sco&lt;/SPAN&gt;ped to your schema, using MATCH COLUMNS&amp;nbsp;to dynamically find the business key column across tables. &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/abac/common-patterns" target="_blank"&gt;Here&lt;/A&gt; is some useful documentation.&lt;/P&gt;
&lt;P&gt;You can refer to &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/abac/performance" target="_blank"&gt;this&lt;/A&gt; page for details on the performance impact. In general try to keep lookup tables and opt for simple UDFs.&lt;/P&gt;
&lt;P&gt;Refer to the best practices documented &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/abac/best-practices" target="_blank"&gt;here&lt;/A&gt;.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Let us know if you hit any issues. Happy to help.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 14 Oct 2026 11:27:44 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173216#M3050</guid>
      <dc:creator>Ashwin_DSA</dc:creator>
      <dc:date>2026-10-14T11:27:44Z</dc:date>
    </item>
    <item>
      <title>Re: Row level Data  MASKING on multiple tables</title>
      <link>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173342#M3051</link>
      <description>&lt;DIV class=""&gt;&lt;DIV&gt;The recommended approach for applying filtering and masking consistently across large numbers of tables is &lt;STRONG&gt;Attribute Based Access Control&lt;/STRONG&gt; (ABAC) combined with &lt;STRONG&gt;governed tags&lt;/STRONG&gt;. ABAC policies scale across catalogs and schemas and are defined by higher level admins, generally preventing table owners from overriding them. They are also evaluated more efficiently than per table UDFs. You can configure a single schema level policy (masking any column tagged pii = ssn) that automatically covers all 120 tables without having to write 120 separate ALTER TABLE SET MASK statements. Check the limitations &lt;A href="https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac/requirements#policy-quotas" target="_self"&gt;here&lt;/A&gt;&lt;/DIV&gt;&lt;BR /&gt;&lt;DIV&gt;On the query regarding whether to propagate the attribute or derive it through entitlement and reference tables, both patterns are supported but there are distinct performance trade offs. Using mapping tables inside policy UDFs such as EXISTS (SELECT 1 FROM map_table WHERE principal = session_user() AND attribute = row_value) is possible but use ABAC if feasible. If you must use external lookup tables, keep them small to trigger a broadcast hash join. Large lookup tables will force a slow shuffle join, and you should avoid complex joins or multi hop derivations inside UDFs. For high volume tables missing the masking key, propagating the governance attribute during the silver layer transformation is a good route for performance, while entitlement tables are fine if they are small and keyed on simple equality.&lt;/DIV&gt;&lt;BR /&gt;&lt;DIV&gt;If you are utilizing a medallion architecture with Spark Declarative Pipelines, the right fit is to embed the security attribute during the silver layer transformation by denormalizing it from wherever the relationship natively lives. From there, tag the sensitive columns with governed tags and enforce the rules using one or two schema level ABAC policies.&amp;nbsp;&lt;SPAN&gt;More details &lt;/SPAN&gt;&lt;A style="font-family: inherit; background-color: #ffffff;" href="https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac" target="_self"&gt;here&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Wed, 14 Oct 2026 17:59:07 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-governance/row-level-data-masking-on-multiple-tables/m-p/173342#M3051</guid>
      <dc:creator>balajij8</dc:creator>
      <dc:date>2026-10-14T17:59:07Z</dc:date>
    </item>
  </channel>
</rss>

