// Reading the shelf: Redline Fieldbook Atrium v1.1 · 2026-04
Documentation / Fieldbook · Security /Security/RLS Admin · 21 min

The Row-Level Security editor.

RLS lets you control which rows of a table a user can see, using predicates that reference the active principal. Declarative, fail-closed, and audited.

TypeAdmin
Reading21 min
Revisedv1.1 · 2026-04
Applies toFieldbook 1.1+

/ 01The RLS model

Row-Level Security in Fieldbook is policy-based. A table has zero or more RowPolicy entries. When a user reads, writes, or deletes from the table, the active policies are evaluated against each row and the principal; only rows that pass are visible.

Three properties to remember:

  • Owner bypasses all policies — the Owner role can always see and edit everything (and every Owner read is audited).
  • OR across policies — if any enabled policy grants access, the row is visible.
  • Fail-closed — if a policy errors during evaluation, the row is excluded, not included.

/ 02Row-policy schema

pub struct RowPolicy {
    pub id: String,
    pub name: String,
    pub operation: Option<RowPolicyOperation>,  // Select | Insert | Update | Delete | All
    pub applies_to_roles: Vec<Role>,         // empty = all roles
    pub rules: Vec<RowPredicate>,               // AND-ed together
    pub enabled: bool,
}

pub struct RowPredicate {
    pub field_id: String,
    pub operator: PredicateOp,
    pub value: String,                  // may reference $principal.email, $role, ...
}

/ 03Predicate operators

OperatorSemanticsExample
EqEquals (case-sensitive)team = "alpha"
NeqNot equalstatus != "archived"
ContainsSubstring matchtags ~ "vip"
InMembership in comma-listregion in "eu,uk"
StartsWithPrefix matchaccount_id starts "ENT-"
IsEmptyNull or empty stringarchived_at IsEmpty
IsNotEmptyHas a valueassignee IsNotEmpty

/ 04Variables

Policy values can reference the active principal — the authenticated user opening the file or executing the request. Variables are resolved at evaluation time, never inlined into stored policies.

VariableResolves to
$principal.emailAuthenticated email address
$principal.subOIDC subject identifier
$principal.nameDisplay name
$roleThe role's name string

If a policy uses a variable the session cannot resolve (anonymous session, expired principal), the predicate evaluates to false and the row is excluded.

/ 05Evaluation logic

  1. Owner shortcut

    If the principal's role is Owner, the row is visible. Audit-only.

  2. Collect enabled policies

    Filter row_policies to those that are enabled and whose operation covers the current operation.

  3. Filter to applicable roles

    If applies_to_roles is non-empty, drop policies that do not mention the principal's role.

  4. If no policies remain

    The row is visible. Tables without policies behave like ordinary SQL tables.

  5. Evaluate each remaining policy

    All predicates in a policy must pass (AND). If any policy passes, the row is visible (OR across policies). On evaluation error, the policy is treated as not passing.

  6. Audit

    Aggregate counts of granted vs denied rows recorded in a single RlsFilterApplied entry per request, not per row.

/ 06The visual editor

The RLS editor (desktop and macOS) lets non-engineers compose policies. Three panes:

  • Policy list — every policy on the table, with enable/disable toggle, operation, and role filter
  • Rule builder — predicate-by-predicate construction; field picker, operator picker, value with variable autocomplete
  • Test panel — pick a principal, see which rows would be visible; row counts annotated by which policy granted them

Every save emits RlsPolicyAdded, RlsPolicyModified, or RlsPolicyRemoved.

/ 07Testing policies

Two ways: the test panel (above), or the CLI:

fieldbook rls test FILE \
  --table tbl_clients \
  --as user@firm.com \
  --role Viewer \
  --operation Select

The CLI runs the policies against every row in the table and prints a per-row breakdown — visible, denied, by which policy, with the predicate trace for failed ones. Use this in CI when generating wall policies (see Chinese Wall) to assert isolation before deploy.

Read carefully. Then begin.

Request access Back to documentation