Documentation Index
Fetch the complete documentation index at: https://docs.snackbase.dev/llms.txt
Use this file to discover all available pages before exploring further.
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:
- list: Controls which records appear in list results (row-level filtering).
- view: Controls access to a single record by ID.
- create: Validates whether a new record can be created.
- update: Controls whether an existing record can be modified.
- 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").
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
| Variable | Description | Example |
|---|
@request.auth.* | The authenticated user’s data | id, email, role, account_id |
@request.data.* | The incoming data (create/update only) | @request.data.status |
fieldname | Direct access to record fields | created_by, status, title |
Operators
| Category | Operator | Description | Example | | | | |
|---|
| Comparison | = | Equal to | created_by = @request.auth.id | | | | |
| != | Not equal to | status != "archived" | | | | |
| < > | Less/Greater than | priority > 10 | | | | |
| <= >= | Less/Greater or equal | amount >= 100 | | | | |
| ~ | LIKE (string match) | title ~ "draft%" | | | | |
| Logical | && | Logical AND | status = "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
| Field | Description |
|---|
id | Auto-generated record identifier |
account_id | Account/tenant identifier (auto-set) |
created_at | Record creation timestamp (auto-set) |
updated_at | Record update timestamp (auto-set) |
created_by | User ID who created the record (auto-set) |
updated_by | User 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