Manage granular policies(管理细粒度策略)¶
Granular policies allow you to configure row-level security for datasets and objects. They are used by restricted views and object security policies to determine which specific rows or object instances a user has permission to access.
A granular policy is a set of rules and logical operators that compare user attributes, columns or properties, and values to determine which data the user can see. Granular policies are flexible and support a range of comparisons and terms.
Design granular policies¶
Before creating a granular policy, consider the following questions:
- How do you want to restrict access to the data?
- What user attributes can you use in the policy?
- On which columns or properties could your policy depend?
- Which Markings propagate through the pipeline but could be unmarked when creating the resource?
- How will you grant permissions to new users?
Recommendations¶
We recommend the following guidelines when designing a granular policy:
- Keep it simple: Before creating a granular policy, write down the policy you want to enforce. Determine the minimum set of conditions required for that policy. The more complex the policy, the harder it will be to manage and verify.
- Make sure policy columns are non-null: Rows with null values in a policy column will be inaccessible to all users. Having null values in the policy column will also cause issues with syncs and downstream processes (such as Phonograph syncs).
- Leverage the pipeline: To reduce the complexity of policies that do not fit well with the current data shape or fields, use the pipeline to compute columns that will make policy writing easier. Try to handle complexity in the pipeline rather than in the granular policy.
- Consider using a dedicated policy column: Changes made to columns in the backing dataset referenced in your policy may break the policy assumptions. To protect a policy from this risk, consider separating out the logic that decides the policy and creating a dedicated column (or columns) for the policy to reference.
- Use attributes: Attribute-based policies can often be the simplest option. Attributes can be pulled from SSO or posted via a user manager.
- Use Markings: Apply a Marking to the backing dataset of your policy to guarantee its protection and ensure that it is only visible to users who have access to the Marking. You can stop inheriting the Marking in the resource since the granular policy already controls which rows a user can see. If the sensitive data has been marked at the source and the Marking has been correctly propagated, there should be no need for a new Marking when creating the resource.
User attributes¶
Below is a list of supported user attributes in granular policies:
- User ID: A unique ID generated by Foundry for each user.
- Username: A unique ID provided by the user's identity provider at login.
- Group IDs: The IDs of all the groups that have the user as a member (direct and inherited).
- Group names: The names of all the groups that have the user as a member (direct and inherited).
- Authorized group IDs: This is an advanced concept related to scoped sessions. Contact your Palantir administrator if you plan to use granular policies with scoped sessions.
- Organization Marking IDs: The Marking IDs of all organizations that have the user as a member (primary and guest). Note that these are Marking IDs which are UUIDs, not Organization IDs that start with
ri.multipass..organization. - Marking IDs: The IDs of all Markings that the user has permission to view.
- Custom attributes: Any custom attributes configured by your identity provider in Control Panel.
When referencing a user, group, or organization, the policy requires the unique identifier (UUID) in both the policy column and the policy definition. Specifying names instead of IDs is not supported to prevent renaming-related issues.
Policy comparisons¶
Granular policies support the following comparison types:
- Equal: Both the left and right side of the comparison must be single-valued (not a collection) and of the same type.
- Intersects: At least one side must be a collection, and both must be of the same type (or collection of that type).
- Subset of: At least right side must be a collection, and both must be of the same type (or collection of that type).
- Superset of: At least left side must be a collection, and both must be of the same type (or collection of that type).
- Less Than: Both the left and right side of the comparison must be single-valued (not a collection) and of the same type.
- Less Than or Equal: Both the left and right side of the comparison must be single-valued (not a collection) and of the same type.
- Greater Than or Equal: Both the left and right side of the comparison must be single-valued (not a collection) and of the same type.
- Greater Than: Both the left and right side of the comparison must be single-valued (not a collection) and of the same type.
:::callout{theme="neutral"} Object security policies do not support less/greater than comparison operators. :::
Policies are defined as templates into which user attributes, group memberships, and data values can be filled. When the consuming application requests data (such as in Contour), the template is converted into a query. This query returns only rows or objects specific to the user's attributes and permissions.
Policy limitations¶
A single policy can have up to ten comparisons. Granular policies weigh each comparison in the policy depending on whether the policy is comparing a collection or a constant against a field:
- A comparison of a constant against a field is given a weight of 1.
- A comparison of a collection against a field is given a weight of 1,000.
- A marking condition is given a weight of 3,000.
- The sum of the weights across all the comparisons in a policy must be under 10,000.
For example, in a basic policy:
- Rule (1) has a weight of 1 since it is matching a constant (the user's ID) against a field.
- Rule (2) has a weight of 1,000 since it is matching a collection (all the groups the user is a member of) against a specific group.
- The sum of the weights in this policy is 1,001 (well under the limit of 10,000).
The current policy construction limit is designed to put minimal constraints on a particular policy design. It provides little protection against a policy that could overwhelm weight limits.
If you receive weight limit errors when constructing policies, contact Palantir Support for assistance.
Policy management¶
When you manage granular policies, consider two goals:
- Transparency: Anyone responsible for managing data access should know the policies and how the policies interact with data in the platform.
- Robust change management: Policy management should be an orderly, organized process. Always review and manage changes before applying them.
Managing integrity of data pipelines¶
Granular policies introduce a set of assumptions about the data that backs them. Therefore, granular policies will only correctly control access to data as long as these assumptions are true. Consider whether the use case requires building out machinery to ensure that those assumptions hold and data stays secured if those assumptions are broken.
One way to solve this problem is by introducing a step in the pipeline directly upstream of the resource that checks the assumptions made about the data. These checks might include:
- Invariants: Write a list of invariants that will force the downstream build to fail if they are not true. For example, assume that whenever an
event_occurred_in_statehas the valueNY, another column in the dataset calledstate_nameshould have valueNew York. Have the transform check that this is true before surfacing this data to users. - Statistics: Define a set of statistics and the range they should always be within. For example, a granular policy may be used to enforce access controls mirroring an organization hierarchy; each user can only see data about individuals below them in the hierarchy. Have the transform assert that if more than 20% of the hierarchy changes from one day's build to the next, something is wrong. At this point, users responsible for policy management should check to ensure everything is correct before surfacing this data to users.
中文翻译¶
管理细粒度策略¶
细粒度策略(Granular policies)允许您为数据集和对象配置行级安全。它们被受限视图和对象安全策略用于确定用户有权访问哪些特定行或对象实例。
细粒度策略是一组规则和逻辑运算符,用于比较用户属性、列或属性以及值,以确定用户可以查看哪些数据。细粒度策略非常灵活,支持多种比较方式和条件。
设计细粒度策略¶
在创建细粒度策略之前,请考虑以下问题:
- 您希望如何限制对数据的访问?
- 您可以在策略中使用哪些用户属性?
- 您的策略可能依赖哪些列或属性?
- 哪些标记(Markings)会通过管道传播,但在创建资源时可以取消标记?
- 您将如何向新用户授予权限?
建议¶
在设计细粒度策略时,我们建议遵循以下准则:
- 保持简单: 在创建细粒度策略之前,先写下您要实施的策略。确定该策略所需的最小条件集。策略越复杂,管理和验证就越困难。
- 确保策略列非空: 策略列中包含空值的行将对所有用户不可访问。策略列中的空值还会导致同步和下游流程(如 Phonograph 同步)出现问题。
- 利用管道: 为降低与当前数据形状或字段不匹配的策略的复杂性,请使用管道计算便于编写策略的列。尽量在管道中处理复杂性,而不是在细粒度策略中处理。
- 考虑使用专用策略列: 对策略引用的底层数据集中的列进行更改可能会破坏策略假设。为保护策略免受此风险影响,请考虑将决定策略的逻辑分离出来,并创建专用列供策略引用。
- 使用属性: 基于属性的策略通常是最简单的选择。属性可以从 SSO 获取,也可以通过用户管理器发布。
- 使用标记: 对策略的底层数据集应用标记,以确保其受到保护,并确保只有有权访问该标记的用户才能看到该数据集。您可以在资源中停止继承该标记,因为细粒度策略已经控制了用户可以查看哪些行。如果敏感数据已在源头标记,并且标记已正确传播,则在创建资源时无需添加新标记。
用户属性¶
以下是细粒度策略中支持的用户属性列表:
- 用户 ID(User ID): Foundry 为每个用户生成的唯一 ID。
- 用户名(Username): 用户在登录时由其身份提供商提供的唯一 ID。
- 组 ID(Group IDs): 包含该用户的所有组的 ID(直接和继承)。
- 组名(Group names): 包含该用户的所有组的名称(直接和继承)。
- 授权组 ID(Authorized group IDs): 这是一个与作用域会话相关的高级概念。如果您计划将细粒度策略与作用域会话一起使用,请联系您的 Palantir 管理员。
- 组织标记 ID(Organization Marking IDs): 包含该用户的所有组织的标记 ID(主要和访客)。请注意,这些是 UUID 格式的标记 ID,不是以
ri.multipass..organization.开头的组织 ID。 - 标记 ID(Marking IDs): 用户有权查看的所有标记的 ID。
- 自定义属性(Custom attributes): 您的身份提供商在控制面板中配置的任何自定义属性。
在引用用户、组或组织时,策略需要在策略列和策略定义中都使用唯一标识符(UUID)。不支持使用名称代替 ID,以防止与重命名相关的问题。
策略比较¶
细粒度策略支持以下比较类型:
- 等于(Equal): 比较的左右两侧必须都是单值(非集合)且类型相同。
- 交集(Intersects): 至少一侧必须是集合,且两侧类型必须相同(或为该类型的集合)。
- 子集(Subset of): 至少右侧必须是集合,且两侧类型必须相同(或为该类型的集合)。
- 超集(Superset of): 至少左侧必须是集合,且两侧类型必须相同(或为该类型的集合)。
- 小于(Less Than): 比较的左右两侧必须都是单值(非集合)且类型相同。
- 小于或等于(Less Than or Equal): 比较的左右两侧必须都是单值(非集合)且类型相同。
- 大于或等于(Greater Than or Equal): 比较的左右两侧必须都是单值(非集合)且类型相同。
- 大于(Greater Than): 比较的左右两侧必须都是单值(非集合)且类型相同。
:::callout{theme="neutral"} 对象安全策略不支持小于/大于比较运算符。 :::
策略被定义为模板,可以填入用户属性、组成员身份和数据值。当消费应用程序请求数据时(例如在 Contour 中),该模板会被转换为查询。此查询仅返回与用户属性和权限相关的行或对象。
策略限制¶
单个策略最多可以有十个比较条件。细粒度策略根据比较的是集合还是常量与字段进行比较,对策略中的每个比较条件进行加权:
- 常量与字段的比较权重为 1。
- 集合与字段的比较权重为 1,000。
- 标记条件的权重为 3,000。
- 策略中所有比较条件的权重总和必须低于 10,000。
例如,在一个基本策略中:
- 规则 (1) 的权重为 1,因为它将常量(用户的 ID)与字段进行匹配。
- 规则 (2) 的权重为 1,000,因为它将集合(用户所属的所有组)与特定组进行匹配。
- 该策略的权重总和为 1,001(远低于 10,000 的限制)。
当前的策略构建限制旨在对特定策略设计施加最小约束。它对于可能超出权重限制的策略提供的保护有限。
如果在构建策略时收到权重限制错误,请联系 Palantir 支持寻求帮助。
策略管理¶
在管理细粒度策略时,需要考虑两个目标:
- 透明度: 任何负责管理数据访问的人员都应了解策略以及策略如何与平台中的数据交互。
- 稳健的变更管理: 策略管理应是一个有序、有组织的过程。在应用变更之前,务必先审查和管理变更。
管理数据管道的完整性¶
细粒度策略引入了关于其底层数据的一系列假设。因此,只有当这些假设成立时,细粒度策略才能正确控制对数据的访问。请考虑您的用例是否需要构建机制来确保这些假设成立,并在假设被打破时确保数据安全。
解决此问题的一种方法是在资源的上游管道中引入一个步骤,用于检查对数据所做的假设。这些检查可能包括:
- 不变性检查(Invariants): 编写一组不变性条件,如果这些条件不成立,将强制下游构建失败。例如,假设每当
event_occurred_in_state的值为NY时,数据集中名为state_name的另一列应具有值New York。让转换在将此数据展示给用户之前检查这一点是否成立。 - 统计检查(Statistics): 定义一组统计指标及其应始终保持在的范围内。例如,细粒度策略可用于实施反映组织层级的访问控制;每个用户只能查看层级中低于其自身级别的个人数据。让转换断言,如果层级在一天构建到第二天构建之间变化超过 20%,则说明出现了问题。此时,负责策略管理的用户应进行检查,确保一切正确,然后再将此数据展示给用户。