🚧 FastCMS is under active development — not ready for production use. APIs and features may change without notice.
FastCMS
Security

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

RuleCollectionsControls
list_ruleBase, AuthWho can list/search records
view_ruleBase, AuthWho can view a single record
create_ruleBase, AuthWho can create new records
update_ruleBase, AuthWho can update records
delete_ruleBase, AuthWho can delete records
manage_ruleAuth onlyWho can manage user accounts (password reset, verification, etc.)

Rule Syntax

Available variables:

VariableDescription
@request.auth.idCurrent logged-in user's ID
@request.auth.roleCurrent user's role
@request.auth.emailCurrent user's email
@record.field_nameValue of any field in the record

Operators: =, !=, && (AND), \|\| (OR)

Common Patterns

Public Access (no rule)

list_rule: null

Everyone 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:

localhost:8000/admin/collections/posts

Edit Collection — posts

Manage schema and access control rules

Schema Fields

idauto
createdauto
updatedauto
titletextrequired
contenteditor
publishedbool
categoryrelation
cover_imagefile

Access Control Rules

Public (no rule)
Public (no rule)
@request.auth.id != ""
@request.auth.id = @record.user_id
@request.auth.role = "admin"

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:changed

Both 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

  1. Start Restrictive — begin with strict rules and loosen as needed
  2. Test Thoroughly — verify rules work for each user role
  3. Use Owner Patterns — most apps need "owner can edit" rules
  4. Admin Override — allow admins to override most restrictions
  5. Document Rules — add comments explaining complex access logic

On this page