Managing access
An access policy controls who can see what in a workspace’s data. One policy can do any of three things:
- Restrict columns (member-level security) — hide specific dimensions or measures from some people. Analysts see
salary; everyone else doesn’t. - Restrict rows (row-level security) — filter the data down to the rows a person is allowed to see. Each salesperson sees only their own accounts.
- Mask values (data masking) — keep a column visible but replace its values, so a person knows the field exists without seeing the real data.
Policies are defined in the semantic model, on the cubes and views they protect. This page explains how they behave; for the exact YAML, see the access policies reference.
How policies decide access
Section titled “How policies decide access”Policies are built on the groups and user attributes you assign to members (see user management):
- A policy targets one or more groups — it applies to the people in those groups.
- Inside a policy, user attributes let you make the rule personal. A filter like “
salesperson_idequals the user’ssalesperson_idattribute” gives every salesperson a different slice of the same dataset from a single policy.
Deny by default
Section titled “Deny by default”The most important rule: as soon as one policy is defined on a cube or view, access is denied to everyone who doesn’t match a policy. Before any policy exists, the data is open to the workspace; the moment you add one, you’ve switched that dataset to allowlist mode. So when you protect a dataset, make sure every group that should keep access has a policy — including, often, an admin or analyst group with full access.
Matching multiple policies
Section titled “Matching multiple policies”A person can belong to multiple groups and therefore match multiple policies at once. When that happens the policies combine:
- Columns add up — the person sees the union of every column their matching policies allow.
- Row filters stack — the person sees only the rows that satisfy all of their matching policies’ filters (the intersection).
In short: matching more policies can only widen the columns you see, and can only narrow the rows.
Default groups: the agent vs. the interface
Section titled “Default groups: the agent vs. the interface”Every query carries one of two built-in groups, depending on who’s asking:
| Group | Added automatically when… |
|---|---|
streya-llm | The agent queries the data to answer a question. |
streya-ui | Data is queried directly from the interface by a person. |
This lets you treat the agent and the human differently for the same data. The canonical use is PII: mask sensitive columns from streya-llm so the agent can reason over the shape of the data without ever reading raw personal details, while allowing streya-ui to display the real values to the person who’s authorized to see them.
# Mask email from the agent, show it in the interfaceaccess_policy: - group: streya-ui member_level: includes: "*"
- group: streya-llm member_level: includes: "*" member_masking: includes: - email - phoneWriting access policies
Section titled “Writing access policies”Policies live alongside the rest of your model, defined together with the Streya team during modeling. The access policies reference documents the full schema — targeting groups, conditions, column rules, masking, and row filters — with examples.