RLS Parameters (Row-Level Security)
Restrict which rows of data an organization can see using RLS parameters: how to define them in SBT, what subscribers see at install, and how to write model code that filters correctly.
New to SBT? Start with the SBT Overview. Everything on this page was verified working in production on sbt 1.0.13 (August 2026).
Two things called "RLS" at Seek
Seek currently has two different mechanisms people call row-level security. Do not mix them up.
Sigma user attributes — security applied at the dashboard layer, per user, using Sigma attribute values (the
SEEK_ORG_FILTERSpattern). This is how existing GTM apps restrict data today.SBT RLS parameters — security applied at the data layer, per organization, using a parameter marked
rls: truein your model config. The app's output tables are physically filtered by the values the organization chose at install time.
This article covers the second one.
What an RLS parameter does
A normal parameter is a knob anyone with variant access can turn. An RLS parameter is different in three ways:
It gates the install. When an organization installs (or upgrades to) an app version with an RLS parameter, they see a Set Data Access screen and cannot proceed until they choose values. The screen says: "This app requires [PARAM] selection(s) to define the data you will have access to in this app."
Its values come from a list you control. The subscriber picks from a dropdown populated by your
values_query. They cannot type arbitrary values.It is multi-select and stored as a list. The chosen values appear on the variant card with a shield icon, as a list (for example
['West']). Your model code must handle a list.
Defining an RLS parameter
An RLS parameter is a normal model variable with two extra requirements: rls: true and a values_query.
In your model config yaml:
models:
- name: region_share
config:
language: python
materialized: table
type: output
write_mode: overwrite
packages:
- "snowflake-snowpark-python"
variables:
- name: REGION_FILTER
display_name: Region Filter
type: string
default: East
rls: true
values_query: regionsAnd the helper file helpers/regions.sql:
select distinct REGION as value, REGION as label
from <YOUR_DB>.<YOUR_SCHEMA>.<YOUR_TABLE>Both column aliases are required — a values query must return exactly two columns named value and label (the rule is explained in Helpers & the Run Context).
⚠️ Known issue: if your values query is missing, or returns columns with any other names, the Set Data Access dropdown renders empty and the page returns a 500 error. The install cannot proceed and there is no helpful error message. sbt will happily build and publish the broken app. Until validation is added, triple-check the value / label aliases before publishing.
Writing model code that uses an RLS parameter
RLS values arrive as a list, because subscribers can select more than one. Filter with isin, never with ==. An equality comparison against a list silently matches nothing and your output table comes back empty with no error.
def model(session, seek):
from snowflake.snowpark.functions import col
import ast
region = seek.params['REGION_FILTER']
# The value may arrive as a list or as a stringified list. Handle both.
if isinstance(region, str) and region.strip().startswith('['):
region = ast.literal_eval(region)
if not isinstance(region, (list, tuple)):
region = [region]
df = session.table(seek.models['upstream_model'])
return df.filter(col('REGION').isin(list(region)))What the subscriber experiences
They install the app (or upgrade to a version that has an RLS parameter).
The Set Data Access screen appears with a required multi-select for each RLS parameter. The options come from your values query, which the platform runs at that moment.
They pick values and click Save & Manage Variant.
Saving triggers a sync engine reconciliation and completes the install. The chosen values appear on the variant card with a shield icon.
Runs filter data to the chosen values.
Current limitations (verified August 2026)
Selections are not remembered across versions. Every upgrade to a new app version re-opens Set Data Access with an empty selection, even if the organization already chose values. Re-select on every upgrade. (Improvement requested.)
The values query must be able to run against real tables at install time. If the tables behind it are missing or inaccessible to the platform, the dropdown will be empty.
Values in your source data that you may not expect (including placeholder values like "NA") will appear as options, because the values query faithfully returns whatever is in the data.
Troubleshooting
Related articles
⏭️ Next: Publisher Snowflake Setup (Grants)