Skip to main content
Row-level security means different users see different rows of the same table — a sales rep sees only their own deals, a regional manager sees only their region. In Peaka you implement this with the current_user_props() SQL function: it returns properties of the user running the query, so a single saved query can filter itself for whoever executes it.

How it works

Every query in Peaka runs with the identity of the user who executes it — whether it comes from the Studio, the Query API, a BI tool, or an embedded app. The current_user_props(key) function exposes that identity inside SQL: All keys return a varchar. If the property is not available — or the query runs without a user identity — the function returns an empty string, so identity-based filters simply match no rows rather than exposing data.

1. Test the function

Run this in the SQL editor to see your own identity:

2. Write a self-filtering query

Add a WHERE clause that compares a column against the current user. For a CRM table where every deal has an owner_email column:
When Jane runs this query she gets only her deals; when another rep runs the same query, they get theirs. No per-user copies, no application-side filtering.

3. Save and share the query

Save the statement as a Peaka query and share the query with your users instead of the underlying table. The filter travels with the query, and each consumer — in the Studio, over the Query API, or in an embedded app — is automatically limited to their own rows.
Row-level security lives in the query, not on the table. A user who can query the base table directly can bypass the filter — so grant your consumers access to the saved query, not to the raw catalog table.

4. Use a mapping table for indirect relationships

Often your data doesn’t contain user emails directly — deals belong to regions, and users are assigned to regions elsewhere. Model that with a small mapping table (a Peaka Table works well): user_regions Then join through it in your shared query:
Access management now becomes data management: to change what someone sees, edit a row in user_regions — no query changes needed. A user with no row in the mapping table sees nothing.

Things to keep in mind

  • current_user_props() always returns varchar. Cast when comparing against numeric columns: CAST(current_user_props('id') AS ...) or cast the column instead.
  • An unknown key returns an empty string rather than an error — double-check key spelling, since a typo silently filters out all rows.
  • User properties such as email and name are cached for a few minutes, so profile changes may take up to five minutes to be reflected in query results.
  • Row-level security controls which rows a user sees. To control what’s inside sensitive columns, combine it with tag-based column masking.