Row Level Security Doc Review 2026 05 04
Row Level Security Documentation Review - May 4, 2026
Request Summary
User Request: Review the Row Level Security (RLS) feature, write/maintain a single canonical article (likely in Getting Started) covering every aspect of the feature, update related articles (filtering, user logins, custom domains, security overview, user access management) so they cross-reference RLS, and cover the API user login flow that inherits RLS. Avoid mentioning hidden or removed features.
Date: May 4, 2026
Branch: moe-feature/ai-article-updates
What Was Found
Canonical RLS article already exists
The canonical guide already lives at exported-articles/Getting Started/(No Section)/2056-row-level-security.html. Most of it lined up with the codebase, but several details had drifted from the current builder UI and Domain API implementation, so the article was corrected rather than replaced.
Related articles already cross-link to RLS
What Was Changed
1. Corrected the policy wizard step ordering
The article previously listed the five-step wizard as Who → Operations → Records → Effect → Field Level. The actual wizard in resources/assets/client/v2/tpl/databuilder/databuilder-security-policy-modal.html is:
- Who can use this access?
- Which operations are allowed?
- Which records can they access?
- Which fields should be shown or hidden?
- Policy Details (name, description, priority)
The article was updated to reflect that exact ordering. The Allow / Restrict effect is not a per-policy step in the UI — it is derived from the table's Default Behaviour in databuilder-security.js via getPolicyEffectFromDefaultBehavior(). The article now has a separate "Allow vs Restrict" section explaining that.
2. Documented the actual field display modes
Field-level masking modes were documented generically. They have been replaced with the four real modes from the policy modal: Mask with asterisks, Mask with dots, Blur, and Blank, plus the option to fully Hide the field. These map to the values mask_asterisks, mask_dots, mask_blur, blank, and hide handled by resolveFieldRestrictions() in app/Services/RlsPolicyService.php.
3. Removed reference to "Smart Templates"
The article previously told builders to look for "Smart Templates" on a freshly enabled table. The Quick Setup / Smart Templates UI is currently commented out in databuilder-security.html, so per the user's instruction not to talk about hidden features, that wording was removed. The article instead points to the per-step shortcuts that are visible (e.g. Allow Only Me, "records connected to the logged-in user") in step 3 of the wizard.
4. Fixed Domain API route parameter name
The article and the Logins article both used /data/{table_slug}. The actual route in routes/web-domain.php and routes/web-subdomain.php is /data/{api_slug} — corrected in both files.
5. Tightened the "no policies = no access" callout
The previous warning said an enabled-but-empty table "blocks all access" universally. The actual behaviour is governed by deny_default in RlsPolicyService::evaluate(), which is itself driven by the table's Default Behaviour. The callout was rewritten to advise adding at least one Allow policy (or a Bypass Role) for legitimate users, without overstating how the default flag works.
6. Filtering Data — added a second RLS reminder
The Filtering Data article (1069-filtering-data.html) already had a top-level callout explaining that component-level filters run on top of RLS. A second short callout was added to the App Side Filter Menu section so that anyone reading specifically about Add Filters and Filter Tabs sees the same guarantee — front-end filters can only narrow what RLS already returned.
Codebase Cross-Checks
Before editing the article I read or grep'd the following sources to make sure every claim still matches the implementation:
app/Services/RlsPolicyService.php— policy evaluation, scope gate, bypass roles, allow/restrict combination, field-restriction resolver, priority filtering (getEffectivePolicies).app/Http/Controllers/Api/DomainApiController.php— Domain API auth flow, master switch on the Users table, scope-based table eligibility for/data.routes/web-domain.phpandroutes/web-subdomain.php— confirmed/login,/logout,/data,/data/{api_slug}.resources/assets/client/v2/tpl/databuilder/databuilder-security.htmlanddatabuilder-security-api.html— Security tab and Security API tab UI.resources/assets/client/v2/tpl/databuilder/databuilder-security-policy-modal.html— confirmed the five wizard step titles and field-display modes.resources/assets/client/v2/controllers/databuilder/databuilder-security.js— confirmedgetPolicyEffectFromDefaultBehavior()and that Allow/Restrict is derived from the table's default behaviour.resources/assets/client/v2/controllers/rls-overview-ctrl.js— confirmed the RLS Overview / "View Permissions As" simulator described in the article still exists and matches.
Codebase Changes
No application code changes were necessary. Every behaviour the user asked the doc to explain is already implemented; the only drift was in the documentation. The work was strictly:
- Edit
exported-articles/Getting Started/(No Section)/2056-row-level-security.html— wizard step order, field display modes, Smart Templates removal, default-behaviour callout, route parameter name. - Edit
exported-articles/Getting Started/(No Section)/1069-filtering-data.html— added an RLS callout to the App Side Filter Menu section. - Edit
exported-articles/Login and SSO/(No Section)/1315-working-with-user-logins.html— corrected{table_slug}to{api_slug}in the API User Logins section.
Why
RLS is the foundational data-layer security mechanism in Tadabase, and a single canonical article needs to describe it accurately because every other article (filtering, custom domains, user logins, security overview) now links to it. Where the article had drifted from the builder UI — wizard step ordering, field-mask options, references to a feature whose UI is currently hidden, and a wrong route parameter — those were exactly the kind of details that lead to support tickets ("the docs say X, the builder shows Y"). Tightening the article keeps it the single source of truth across the doc set.
Features Intentionally Not Mentioned
- Smart Templates / Quick Setup cards — the section is present in
databuilder-security.htmlbut commented out, so it is not part of the live builder today. - Self-service partner registration over the Domain API — explicitly excluded by spec; the article correctly says identities are provisioned through the platform console.
We'd love to hear your feedback.