Access Control Rules
Row-level security with a powerful expression language. Control exactly who can list, view, create, update, delete, and manage records.
Access Control Rules
Every collection has access control rules that determine who can perform which operations. Base collections have five rules; auth collections add a sixth — manage_rule.
Rule Types
| Rule | Collections | Controls |
|---|---|---|
list_rule | Base, Auth | Who can list/search records |
view_rule | Base, Auth | Who can view a single record |
create_rule | Base, Auth | Who can create new records |
update_rule | Base, Auth | Who can update records |
delete_rule | Base, Auth | Who can delete records |
manage_rule | Auth only | Who can manage user accounts (password reset, verification, etc.) |
Rule Syntax
Available variables:
| Variable | Description |
|---|---|
@request.auth.id | Current logged-in user's ID |
@request.auth.role | Current user's role |
@request.auth.email | Current user's email |
@record.field_name | Value of any field in the record |
Operators: =, !=, && (AND), \|\| (OR)
Common Patterns
Public Access (no rule)
list_rule: nullEveryone can access — no authentication required.
Authenticated Users Only
list_rule: "@request.auth.id != ''"Only logged-in users can list records.
Admin Only
list_rule: "@request.auth.role = 'admin'"
create_rule: "@request.auth.role = 'admin'"
delete_rule: "@request.auth.role = 'admin'"Owner Only
list_rule: "@request.auth.id = @record.user_id"
update_rule: "@request.auth.id = @record.user_id"Users can only see/edit records they own.
Owner OR Admin
update_rule: "@request.auth.id = @record.user_id || @request.auth.role = 'admin'"
delete_rule: "@request.auth.id = @record.user_id || @request.auth.role = 'admin'"Visual Editor
Rules are editable directly in the collection form in the admin dashboard — each rule type gets its own input field:
Edit Collection — posts
Manage schema and access control rules
Schema Fields
Access Control Rules
Real-World Example: Vendor System
Scenario: Vendors manage their own products but cannot see other vendors' products.
Step 1: Create "vendors" auth collection
{"name": "vendors", "type": "auth"}Step 2: Create "products" base collection with access rules
{
"name": "products",
"type": "base",
"schema": [
{"name": "vendor_id", "type": "text", "validation": {"required": true}},
{"name": "name", "type": "text", "validation": {"required": true}},
{"name": "price", "type": "number", "validation": {"required": true}}
],
"list_rule": "@request.auth.id = @record.vendor_id",
"view_rule": "@request.auth.id = @record.vendor_id",
"create_rule": "@request.auth.id != ''",
"update_rule": "@request.auth.id = @record.vendor_id",
"delete_rule": "@request.auth.id = @record.vendor_id || @request.auth.role = 'admin'"
}Result:
- Vendors see only their own products
- Vendors can create new products
- Vendors can only update/delete their own products
- Admins can delete any product
Setting Rules via API
curl -X PATCH http://localhost:8000/api/v1/collections/products \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"list_rule": "@request.auth.id = @record.user_id",
"update_rule": "@request.auth.id = @record.user_id || @request.auth.role = 'admin'"
}'The :changed Modifier
Use the :changed modifier inside update_rule expressions to check whether a specific field was changed in the current request.
Syntax:
field_name:changed
@record.field_name:changedBoth forms resolve to true if the field value changed, false if it stayed the same.
Use cases:
# Only admins can change the published status
update_rule: "published:changed = false || @request.auth.role = 'admin'"
# Prevent price changes without admin approval
update_rule: "@request.auth.id = @record.owner_id && price:changed = false"
# Allow role changes only by admins
update_rule: "@request.auth.id != '' && @record.role:changed = false || @request.auth.role = 'admin'"The :changed modifier is only meaningful in update_rule. In other rules, the old record state is empty, so :changed always returns true — avoid using it in create_rule, delete_rule, etc.
Auth Collection: manage_rule
Auth collections have an additional manage_rule that controls access to admin-level user management operations — such as resetting passwords, forcing email verification, or unlocking accounts.
This rule is separate from update_rule so you can allow users to edit their own profile fields while restricting who can perform privileged account operations.
Allow only site admins to manage users:
manage_rule: "@request.auth.role = 'admin'"Restrict management to superadmins in a multi-role setup:
manage_rule: "@request.auth.role = 'superadmin'"Setting manage_rule via API:
curl -X PATCH http://localhost:8000/api/v1/collections/customers \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"manage_rule": "@request.auth.role = '\''admin'\''"
}'If manage_rule is null, management operations are admin-only by default (only accessible via the master admin token).
Best Practices
- Start Restrictive — begin with strict rules and loosen as needed
- Test Thoroughly — verify rules work for each user role
- Use Owner Patterns — most apps need "owner can edit" rules
- Admin Override — allow admins to override most restrictions
- Document Rules — add comments explaining complex access logic