Skip to content

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.

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_id equals the user’s salesperson_id attribute” gives every salesperson a different slice of the same dataset from a single policy.

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.

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:

GroupAdded automatically when…
streya-llmThe agent queries the data to answer a question.
streya-uiData 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 interface
access_policy:
- group: streya-ui
member_level:
includes: "*"
- group: streya-llm
member_level:
includes: "*"
member_masking:
includes:
- email
- phone

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.