Access policies
access_policy is an array on a cube or view that controls column- and row-level access for the people querying it. For the concepts and behavior, see managing access.
access_policy: - group: sales conditions: - if: "{ attributes.is_active }" member_level: excludes: - cost member_masking: includes: - customer_email row_level: filters: - member: salesperson_id operator: equals values: ["{ attributes.salesperson_id }"]Each entry is one policy. A policy applies to a person when its group target matches and all of its conditions are true. Once any policy exists on a cube or view, people who match no policy are denied access entirely.
Policy properties
Section titled “Policy properties”| Property | Type | Description |
|---|---|---|
group | string | The group this policy applies to. Use "*" to apply to everyone. |
groups | array | Several groups in one policy — shorthand for repeating it per group. |
conditions | array | Extra gates; the policy applies only if all evaluate true. See conditions. |
member_level | object | Which columns are visible. See member_level. |
member_masking | object | Which visible columns have their values masked. See member_masking. |
row_level | object | Which rows are visible. See row_level. |
Provide exactly one of group or groups. The three rule blocks (member_level, member_masking, row_level) are each optional; a policy with none simply grants matching users full access.
conditions
Section titled “conditions”A list of gates that must all be true for the policy to take effect. Each is an if expression, typically referencing the querying person’s user attributes via attributes.
conditions: - if: "{ attributes.region }" # attribute is present / truthy - if: "{ attributes.clearance_level } >= 3" # comparisonUse conditions to switch a policy on per-person — for example, applying a rule only to full-time staff or to a particular region — without creating a separate group.
member_level
Section titled “member_level”Controls which dimensions and measures the policy exposes. Provide either includes or excludes, not both.
member_level: includes: "*" # all columns… excludes: # …is invalid alongside includes — pick one - cost - margin| Key | Meaning |
|---|---|
includes | Allowlist: only these columns are visible. "*" means all. |
excludes | Blocklist: every column except these is visible. |
member_masking
Section titled “member_masking”Keeps columns visible but replaces their values. Use it when a person should know a field exists — and query around it — without reading the raw data. Defined alongside member_level in the same policy. Provide either includes or excludes, not both.
member_masking: includes: # mask these columns - customer_email - phone| Key | Meaning |
|---|---|
includes | Mask these columns. "*" masks all visible columns. |
excludes | Mask everything except these. |
Masking differs from member_level exclusion: excluded columns disappear; masked columns remain queryable but return obscured values.
The mask property
Section titled “The mask property”A column listed in member_masking must define a mask property on its dimension or measure, which sets what the value is replaced with when masked. The mask is either a static value or an SQL expression:
dimensions: - name: customer_email sql: customer_email type: string mask: sql: "CONCAT(LEFT({CUBE}.customer_email, 2), '***')"
- name: customer_zip sql: customer_zip type: string mask: "REDACTED" # static replacement
measures: - name: total_salary sql: salary type: sum mask: -1 # static replacementWithout a mask, there’s nothing for member_masking to substitute — define one on every column you intend to mask.
row_level
Section titled “row_level”Filters the rows the policy exposes. Holds a filters array; each filter compares a column against one or more values.
row_level: filters: - member: region operator: equals values: ["{ attributes.region }"] - or: - member: status operator: equals values: ["active"] - member: status operator: equals values: ["trial"]| Filter key | Meaning |
|---|---|
member | The dimension to filter on. |
operator | Comparison operator — equals, notEquals, contains, startsWith, endsWith, gt, gte, lt, lte, set, notSet, inDateRange. |
values | Array of values to compare against. Entries may be literals or attributes references such as "{ attributes.salesperson_id }". |
Combining filters
Section titled “Combining filters”Top-level filters in the array are combined with AND — every one must pass. Use explicit and / or blocks to nest other logic:
filters: - and: - member: region operator: equals values: ["{ attributes.region }"] - or: - member: tier operator: equals values: ["gold"] - member: tier operator: equals values: ["platinum"]Multiple matching policies
Section titled “Multiple matching policies”A person can match several policies (through multiple groups). The results combine:
- Columns — the union of what each matching policy allows. Matching more policies can only reveal more columns.
- Row filters — the intersection: the person sees only rows that satisfy every matching policy. Matching more policies can only restrict rows further.
User attributes and built-in groups
Section titled “User attributes and built-in groups”attributesexposes the querying person’s user attributes — the key-value pairs (salesperson_id,region, …) set on their membership. Reference them as{ attributes.<key> }insideconditionsandrow_levelvalues.- Two built-in groups are added automatically to every query:
streya-llmwhen the agent queries, andstreya-uiwhen a person queries from the interface. Target them like any other group — see the guide for the PII-masking pattern.