BackendPermissions
Validate
Validate data on insert and update operations before it reaches the database.
Validate rules check the values a user is trying to write. If the data does not match the rules, the request is rejected with 403 Forbidden before any SQL is executed.
permissions: {
create_orders: {
table: 'main.orders',
roles: ['sales'],
insert: {
columns: ['amount', 'status', 'customer_id'],
validate: {
amount: { $gte: 0 },
status: { $in: ['draft'] },
},
},
},
}A user trying to insert { amount: -50, status: 'draft' } gets rejected because amount fails the $gte: 0 validate rule.
How Validate Works
Validate runs before the query. It compares the request body values against the rules:
- Extract the values from the request body
- Apply each validate operator to the corresponding value
- If any rule fails, return
403with the failing field - If all pass, proceed to query execution
Validate vs. Where
| Where | Validate | |
|---|---|---|
| Purpose | Row-level security (which rows) | Value validation (what values) |
| Applies to | select, update, delete | insert, update |
| Mechanism | Adds WHERE clause | Validates request body |
| Failure | Silently excludes rows | Returns 403 error |
Examples
Range Validation
insert: {
columns: ['amount', 'status'],
validate: {
amount: { $gte: 0, $lte: 100_000 },
},
}
// Allows: { amount: 500 }
// Rejects: { amount: -1 }, { amount: 200_000 }Enum Validation
insert: {
columns: ['status'],
validate: {
status: { $in: ['draft', 'active', 'closed'] },
},
}
// Allows: { status: 'draft' }
// Rejects: { status: 'deleted' }, { status: 'archived' }Multiple Field Validation
insert: {
columns: ['amount', 'status', 'priority'],
validate: {
amount: { $gte: 0, $lte: 100_000 },
status: { $in: ['draft', 'active', 'closed'] },
priority: { $gte: 1, $lte: 5 },
},
}
// All three fields are validated independently
// ALL must pass for the request to proceedUpdate Validation
Validate also applies to update operations, validating the new values:
permissions: {
edit_org_orders: {
table: 'main.orders',
roles: ['editor'],
update: {
columns: '*',
where: { organization_id: { $in: '$user.org_ids' } },
validate: {
status: { $in: ['draft', 'active', 'closed'] },
amount: { $gte: 0, $lte: 100_000 },
},
},
},
}
// User can update orders in their org,
// but only set status to draft/active/closed
// and amount between 0 and 100,000Validate with Session Variables
You can reference $user.* in validate values:
insert: {
columns: ['organization_id', 'name'],
validate: {
organization_id: { $eq: '$user.current_org_id' },
},
}
// Ensures users can only write to their own organizationSupported Operators
All comparison operators are available in validate rules: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin.