A dataset can carry row security rules: declarations, stored with the dataset itself, of which role should see which rows. Each rule pairs a role with a row filter — a predicate over the dataset's columns — so the scoping decision is made once, where the data is defined, rather than re-implemented inside every report that consumes it. This page explains what a rule declares, how the platform checks it, and — just as important — what row security is not, so you choose the right tool when the requirement is a hard guarantee.
The dataset definition establishes the boundary within which later Security-tab rules operate. A published data model or fallback table supplies the data, Grain defines what one row means, Visibility controls who may discover the dataset, and the warehouse table stores the full materialized result. Row-security declarations added after creation slice that result for named roles; they do not change the dataset's grain or physically remove rows.
Choose the broadest legitimate audience first, then decide whether a requirement is advisory consumer-side scoping or a hard exclusion. Use a build-time filter or separate dataset for data that must never enter the materialized table, and use Security-tab role predicates only when every consuming surface is verified to enforce them.
What a rule declares
Row security rules are authored on the Security tab of the dataset workspace. Each rule has:
- A role — the audience the rule scopes. Every active rule must name one; validation blocks a compile otherwise.
- A row filter expression — a SQL predicate over the dataset's columns describing the rows that role should see, for example
RegionCode = 'WEST'on a dataset with a region dimension. - A display order and an active flag — rules are ordered, and inactive rules are ignored entirely.
A dataset can carry several rules, one per audience. The declared meaning is scoping, not permission to open the dataset: members of the named role are meant to see the matching rows of a dataset they can already reach.
How rules are checked
Rules participate in the dataset's design-time machinery. Validate requires every active rule to carry both a role and a non-empty expression, and — when the dataset is bound to a published data model — checks the expression's column references against the model's published schema, so a rule cannot silently name a column that will not exist. Preview lists the active security rules alongside the filters and the generated SQL, making the dataset's full declared contract reviewable in one place before anything is built.
What row security is not
Two boundaries keep expectations honest:
- The materialized table is not per-user filtered. A dataset compiles into a single warehouse table holding the full results of its definition. Row security rules are not baked into the table; they are applied when the dataset is read. Native xMatix dashboards apply them: a dataset tile is filtered to the rules for the viewer's roles — including roles below theirs in the role hierarchy — and a viewer who matches no rule on a secured dataset sees no rows at all (never an unfiltered result). Rules are combined with OR, so a viewer in two audiences sees both slices. Other consumers of the warehouse table (an embedded BI tool reading it directly, an export) do not apply these rules; where the requirement is absolute for those surfaces, use dataset filters instead — a build-time filter genuinely excludes rows from the table — or split the data into separate datasets per audience.
- It is not the application's record security. Record-level security governs who sees which records in the live application. Datasets are separate tables in the analytics warehouse, built from the model's data as defined — a user's operational record permissions do not follow rows into a dataset. The two systems answer different questions: record security protects the operational system; dataset scoping decides what an analytical audience is served.
The practical design rule that follows: build each dataset at the scope of its broadest legitimate audience, use filters or separate datasets for hard exclusions, and use row security rules to express per-role slicing within that audience.
Common questions
Is the dataset's warehouse table filtered per user?
No. Compilation writes one table containing everything the dataset's definition produces — dimensions, measures and build-time filters applied, row security rules not. Per-role scoping happens at read time: native dashboards apply the rules for the viewer's roles on every query (and fail closed when none match). Surfaces that read the warehouse table directly do not, which is why the hard-guarantee tools for those are the ones that shape the table itself: dataset filters, or one dataset per audience.
Does dataset row security replace record-level security?
No — they operate on different data in different places. Record-level security (sharing, restriction rules, profiles) governs live records in the application and keeps doing so regardless of anything in Data Studio. Dataset row security scopes analytical outputs in the warehouse. A user barred from an account record by record security is not automatically barred from aggregate numbers a dataset computed over it — if that matters for your data, scope the dataset accordingly.
Who can define row security rules?
Anyone holding the analytics administration capability (setup.metadata.analytics.manage) — the same grant that covers datasets and data models, since the rules are part of the dataset's definition. There is no separate row-security permission; what there is instead is validation, which refuses to compile a dataset whose active rules are incomplete.
