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.

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.
  • 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_state has the value NY, another column in the dataset called state_name should have value New 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.