本页提供有关使用行筛选器和列掩码筛选表中敏感数据的指导。
什么是行筛选器?
使用行筛选器可以控制用户可以基于自定义逻辑在表中访问的行。 在查询时,行筛选器会评估条件,并仅返回满足该条件的行。 这通常用于实现行级别安全性,例如,将用户限制为来自特定区域、部门或帐户的记录。
行筛选器定义为 SQL 用户定义的函数(UDF),也可以在 SQL UDF 中包装时合并 Python 或 Scala 逻辑。 可以为每个表格应用行筛选器,也可以通过使用受治理的标记在 ABAC 策略中集中管理行筛选器。
什么是列过滤?
列掩码控制用户在特定列中看到的值,具体取决于用户是谁。 在查询时,掩码将每个对列的引用替换为掩码函数的结果。 这样就可以根据用户标识或角色对敏感数据(如 SSN 或电子邮件)进行编辑或转换。
每个列可以有一个掩码。 掩码必须定义为一个 SQL UDF,该 UDF 返回的值类型与被屏蔽的列相同。 SQL UDF 可以选择 调用 Python 或 Scala UDF 来实现复杂的掩码逻辑。 列掩码还可以采用其他列作为输入,例如,根据多个属性改变行为。
与行筛选器一样,列掩码可以按表应用,也可以通过 ABAC 策略集中管理。 它们在查询时运行,并与标准 SQL、笔记本和仪表板无缝集成。
何时应使用动态视图与筛选器和掩码?
动态视图、行筛选器和列掩码都允许你在查询时应用筛选或转换逻辑,但它们在管理、作用域和向用户公开的方式上有所不同。
| 功能 / 特点 | 适用于 | 使用 进行管理 | 命名影响 | 最适合... |
|---|---|---|---|---|
| 动态视图 | 浏览量 | SQL 逻辑 | 创建新的对象名称 | 共享筛选后的数据或跨越多个表格 |
| 行筛选器 | 表格 | ABAC 或映射表 | 表名称未更改 | 与用户或数据标签关联的行级访问控制 |
| 列掩码 | 表/列 | ABAC 或映射表 | 表名称未更改 | 根据身份对敏感列数据进行遮蔽 |
- 如果需要跨一个或多个源表的只读层,尤其是对于数据共享或跨多个输入应用逻辑,请使用动态视图。
- 如果要将逻辑直接应用于表,而无需更改表名称或引入新对象,请使用行筛选器和列掩码。 可以使用 ABAC 策略(推荐)或手动管理这些表。
有关完整比较,请参阅 访问控制方法比较。
如何应用筛选器和掩码
可以通过两种主要方式实现行筛选器和列掩码:
使用 ABAC 策略 (公共预览版):使用受治理的标记和可重用策略集中应用筛选器和掩码。 此方法可在目录和模式之间扩展,并减少逐表配置的需求。 ABAC 策略比手动表级策略更安全,因为它们可由高级管理员定义,不能由表所有者重写,这有助于强制实施集中式访问控制。 在许多情况下,它们的性能也更高,因为评估 ABAC 策略中的筛选和掩码逻辑要比评估特定于表的 UDF 更高效。 Databricks 建议对大多数用例使用 ABAC。 若要使用 ABAC 应用筛选器和掩码,请参阅 Unity 目录基于属性的访问控制(ABAC)。
每个表的手动分配:通过将函数直接分配给单个表和列来应用筛选器和掩码。 此方法可以使用映射表或其他自定义逻辑。 它允许细粒度的特定表控制,但这使得扩展和维护更加困难。 有关详细信息,请参阅 手动应用行筛选器和列掩码。
性能建议
行筛选器和列掩码可以确保用户在筛选和屏蔽操作之前无法查看基表值的内容,从而控制数据的可见性。 它们在常见的用例中响应查询时表现良好。 在不太常见的应用程序中,查询引擎必须选择优化查询性能并防止从筛选/掩码值泄露信息,它将始终做出安全决策,但会对查询性能产生一定影响。 若要最大程度地降低此性能影响,请应用以下建议:
- 使用简单的策略函数: 表达式较少的策略函数通常比更复杂的表达式性能更好。 避免使用映射表和表达式子查询,建议使用简单的 CASE 函数。
- 限制列掩码和掩码函数的数目: 大型表上的多个唯一列掩码可能会损害查询性能。 每个不同的掩码都需要在查询期间进行评估,导致处理开销增加。 仅对包含真正敏感数据的列应用掩码,并尽可能重复使用掩码函数。
- 减少函数参数的数目: Azure Databricks 无法优化对策略函数参数生成的源表的列引用,即使查询中未使用这些列。 使用参数较少的策略函数,因为这些表中的查询的性能会更好。
- 避免添加包含过多 AND 连接符的行筛选器: 由于在给定用户和表的运行时只能解析出一个不同的行筛选器,因此一种常见的方法是将多个所需的策略函数与 组合起来使用 。 但是,随着每增加一个连接词,出现这些连接词包含此表中其他位置提及的组件的几率增加,这些组件可能会影响性能(例如映射表)。 减少连接数来提高性能。
-
在表策略和来自这些表的查询中,使用不会引发错误的确定性表达式: 如果提供的输入无效(例如 ANSI 除法),某些表达式可能会引发错误。 在这种情况下,SQL编译器不得将包含这些表达式(如过滤器)的操作推得太深至查询计划中,以避免出现诸如“除以零”之类的错误,这些错误可能会在过滤和/或掩码操作之前泄露有关值的信息。 使用永远不会引发错误的确定性表达式,例如
try_divide。 -
首选 SQL 而不是 Python UDF:Python UDF 的性能通常比 SQL 低,并且提供了更少的优化机会。 如果必须使用 Python,请在 UDF 不涉及非确定性逻辑或依赖关系时显式标记为
DETERMINISTIC。 - 通过表运行测试查询以衡量性能: 使用行筛选器或列掩码构造实际查询,这些查询表示表所需的工作负荷,并测量性能。 对策略函数进行小修改并观察其效果,直到在筛选和屏蔽逻辑的性能和表现力之间取得良好平衡。
有关 ABAC 策略的 UDF 最佳做法和示例,请参阅 UDF 最佳做法。
限制
- 12.2 LTS 之前的 Databricks Runtime 版本不支持行筛选器或列过滤。 这些运行时安全失败,这意味着如果尝试从这些运行时访问表,则不会返回任何数据。
- Delta Sharing 提供程序无法共享具有行级安全性或列掩码的表。 但是,Delta Sharing 接收者只能将行筛选器和列掩码应用于共享表和外部表,而不能应用于流式表或物化视图。
- 托管的 Iceberg 表不支持行筛选器或列掩码。
- 不能使用 Iceberg REST 目录或 Unity REST API 访问包含行筛选器或列掩码的表。
- 不能将行级别安全性或列掩码应用于视图。
- 按时间顺序查看不适用于行级安全性或列掩码。
- 不支持对具有策略的表中文件的基于路径的访问。
- 不支持与原始策略有循环依赖的行筛选或列屏蔽策略。
- 行筛选器和列掩码不能引用同时具有活动行筛选器或列掩码的表。 在 ABAC 配置中,可以通过从引用表的策略中排除策略函数所有者来解决此问题。
- 对具有行级安全性或列掩码的表不支持深度克隆和浅克隆。
-
MERGE语句不支持包含嵌套、聚合、窗口、限制或不确定函数的行筛选器或列掩码策略的表。 - 低于 17.2 的 Databricks Runtime 版本不支持在具有针对分区列定义的行筛选器或列掩码策略的分区表上使用
DELETE、UPDATE和MERGE。 - 不支持 Delta Lake API。
专用访问模式限制
不能从 Databricks Runtime 15.3 或更低版本上的专用访问计算资源访问具有行筛选器或列掩码的表。 如果为无服务器计算启用了工作区,则可以在 Databricks Runtime 15.4 LTS 或更高版本上使用专用访问模式。 但是,在 Databricks Runtime 15.4 到 16.2 上,仅支持读取操作。 写入操作(包括INSERT、UPDATE和DELETE)需要 DBR 16.3 或更高版本,并且必须使用支持的模式,例如MERGE INTO。
有关详细信息,请参阅 专用计算上的精细访问控制。