Access policies
Access policies provide a holistic mechanism to manage member-level and row-level security for different user groups. You can define access control rules in data model files, allowing for an organized and maintainable approach to security.
Policies
You can define policies that target specific groups and contain member-level and (or) row-level security rules:
cubes:
- name: orders
# ...
access_policy:
# For the `manager` group,
# allow access to all members
# but filter rows by the user's country
- group: manager
member_level:
includes: "*"
row_level:
filters:
- member: country
operator: equals
values: [ "{ userAttributes.country }" ]While you can define access policies on both cubes and views, it is more common to define them on views.
For more details on available parameters, check out the access policies reference.
Policy evaluation
When processing a request, Cube will evaluate the access policies and combine them
with relevant custom security rules, e.g., public parameters for member-level security
and query_rewrite filters for row-level security.
If multiple access policies apply to a request, they are combined together using the OR semantics. For example, if a user has two groups with different policies, the user will get the union of the permissions in these policies.
Member-level access
Member-level security rules in access policies are combined together
with public parameters of cube and view members using the AND semantics.
Both will apply to the request.
When querying a view, member-level security rules defined in the view are not combined together with member-level security rules defined in relevant cubes. Only the ones from the view will apply to the request.
This is consistent with how column-level security works in SQL databases. If you have a view that exposes a subset of columns from a table, it doesnt matter if the columns in the table are public or not, the view will expose them anyway.
Row-level access
Row-level filters in access policies are combined together with filters defined
using the query_rewrite configuration option.
Both will apply to the request.
When querying a view, row-level filters defined in the view are combined together with row-level filters defined in relevant cubes. Both will apply to the request.
This is consistent with how row-level security works in SQL databases. If you have a view that exposes a subset of rows from another view, the result set will be filtered by the row-level security rules of both views.
Common patterns
Restrict access to specific groups
To restrict access to a view to only specific groups, define access policies for those groups. Access is automatically denied to all other groups:
views:
- name: sensitive_data_view
# ...
access_policy:
# Allow access only to the `analysts` group
- group: analysts
member_level:
includes: "*"You can also use the groups parameter (plural) to apply the same policy to multiple groups at once:
views:
- name: sensitive_data_view
# ...
access_policy:
# Allow access to multiple groups using groups array
- groups: [analysts, managers]
member_level:
includes: "*"Filter by user attribute
You can filter data based on user attributes to ensure users only see data they're authorized to access. For example, sales people can see only their own deals, while sales managers can see all deals:
views:
- name: deals_view
# ...
access_policy:
# Sales people can only see their own deals
- group: sales
member_level:
includes: "*"
row_level:
filters:
- member: sales_person_id
operator: equals
values: [ "{ userAttributes.userId }" ]
# Sales managers can see all deals
- group: sales_manager
member_level:
includes: "*"
# No row-level filters - full access to all rowsMandatory filters
You can apply mandatory row-level filters to specific groups to ensure they only see data matching certain criteria:
views:
- name: country_data_view
# ...
access_policy:
# Allow access only to the `sales` and `marketing` groups with country filtering
- groups: [sales, marketing]
member_level:
includes: "*"
row_level:
filters:
- member: users_country
operator: equals
values: ["Brasil"]Troubleshooting
Be careful with the any group shorthand (group: "*") in access
policies that don't restrict access on member and row level. Given that policies for
multiple groups are combined together using the OR semantics,
a policy that allows access for any group without restrictions on a certain level will
effectively grant unrestricted access on that level to all users:
cubes:
- name: orders
# ...
access_policy:
# No access on member level, __full access__ on row level for any group
- group: "*"
member_level:
includes: []
# Some restrictions on row level for the `restricted` group
- group: restricted
row_level:
filters:
- member: country
operator: equals
values: [ "USA" ]In the example above, all users will have full access to all members and all rows of the
orders cube, regardless of their groups, because the first policy applies to any
group and is combined with the second one using the OR semantics.
Custom mapping
Cube cloud platform automatically maps authenticated users to groups for access policies. If you are using Cube Core or authenticating against Core Data APIs directly, you might need to map the security context to groups manually.
A user can have more than one group.
Using securityContext
The userAttributes object is only available in Cube Cloud platform. If you are using Cube Core or authenticating against Core Data APIs directly, you won't have access to userAttributes. Instead, you need to use securityContext directly when referencing user attributes in access policies (e.g., in row_level filters or conditions). For example, use securityContext.userId instead of userAttributes.userId.
cubes:
- name: orders
# ...
access_policy:
- group: manager
row_level:
filters:
- member: country
operator: equals
values: [ "{ securityContext.country }" ]Using roles
In prior versions of Cube, we were using roles instead of groups. We have changed that to groups to avoid conflict with Cube roles.
In Cube Core, you can still use roles. You would need to define context_to_roles instead of context_to_groups.