Skip to main content
SnackBase uses a database-centric rule engine that compiles expression-based rules into efficient SQL WHERE clauses for granular row-level security (RLS).

Overview

In snackbase v0.2, permissions have shifted from a role-based model to a Collection-centric model. Instead of defining what each role can do, you define Rules directly on the collection. Each collection has 5 distinct operations that can be controlled:
  1. list: Controls which records appear in list results (row-level filtering).
  2. view: Controls access to a single record by ID.
  3. create: Validates whether a new record can be created.
  4. update: Controls whether an existing record can be modified.
  5. delete: Controls whether a record can be removed.

Role Management

While rules are defined on collections, they still leverage user roles. Roles are now used as labels/identifiers within rule expressions (e.g., @request.auth.role = "admin").

Performance

Rule expressions are compiled into native SQL. This means:
  • No performance overhead: Checks happen at the database level.
  • Scalable: Works efficiently even with millions of records.
  • SQL-Native: Supports complex joining logic via SQL Macros.

Rule Syntax

Variables

VariableDescriptionExample
@request.auth.*The authenticated user’s dataid, email, role, account_id
@request.data.*The incoming data (create/update only)@request.data.status
fieldnameDirect access to record fieldscreated_by, status, title

Operators

CategoryOperatorDescriptionExample
Comparison=Equal tocreated_by = @request.auth.id
!=Not equal tostatus != "archived"
< >Less/Greater thanpriority > 10
<= >=Less/Greater or equalamount >= 100
~LIKE (string match)title ~ "draft%"
Logical&&Logical ANDstatus = "public" && active = true
``Logical OR`@request.auth.role = “admin”created_by = @request.auth.id`
!Logical NOT!is_locked

Literals

  • Strings: "text" or 'text'
  • Numbers: 123, 45.67
  • Booleans: true, false

Built-in Macros

Macros are reusable expression fragments that simplify common patterns.
  • @has_role("role_name"): Convenience for @request.auth.role = "role_name"
  • @has_group("group_name"): Checks if user is in a specific group
  • @owns_record(): Convenience for created_by = @request.auth.id
  • @is_creator(): Same as @owns_record()

SQL Macros

SQL macros allow you to create custom permission logic using raw SQL queries.

Example: @is_project_member(project_id)

  • SQL Query:
    SELECT count(*) > 0 FROM project_members
    WHERE project_id = $1 AND user_id = @request.auth.id
    
  • Usage in Rule:
    @is_project_member(project_id)
    

System Fields

FieldDescription
idAuto-generated record identifier
account_idAccount/tenant identifier (auto-set)
created_atRecord creation timestamp (auto-set)
updated_atRecord update timestamp (auto-set)
created_byUser ID who created the record (auto-set)
updated_byUser ID who last updated the record

Field-Level Access Control

You can restrict field visibility per operation. This is now managed via list_fields, view_fields, etc. in the collection rules.
{
  "list_fields": ["id", "title", "status"],
  "view_fields": "*"
}

API Management

Collection rules are managed via the Collections API:
  • GET /api/v1/collections/{name}/rules
  • PUT /api/v1/collections/{name}/rules

Common Patterns

1. Public Read Access

  • list_rule: true
  • view_rule: true
  • modify_rules: @request.auth.role = "admin"

2. Owner-Only Access

  • list_rule: created_by = @request.auth.id
  • view_rule: created_by = @request.auth.id
  • update_rule: created_by = @request.auth.id