Writing Effective Policies
Defining Paths with Dynamic Segments
Use dynamic segments (prefixed with $
) to create flexible and reusable policies that apply to multiple documents or collections.
Example:
{
"users/$userId": { ... },
"posts/$postId/comments/$commentId": { ... }
}
In this example, $userId
, $postId
, and $commentId
are placeholders that match any value at that position in the path.
Rules: Controlling Access
Rules determine whether a read or write operation is permitted based on specified conditions.
- Read Rule (
"read"
): Must evaluate to true for a read operation to succeed - Create Rule (
"create"
): Specific rule for document creation - Update Rule (
"update"
): Specific rule for document updates - Delete Rule (
"delete"
): Specific rule for document deletion
Special Variables Available in rules and hooks:
@user.address
: The wallet address of the user making the request@data
: The current state of the document before the write operation@newData
: The proposed state of the document after the write operationget(path)
: Get data at a specific pathgetAfter(path)
: Get data at a specific path after all pending changes in the batch are applied@time.now
: The current server time, if off-chain, this use's Tarobase's server time, and if on-chain it uses the timestamp of the last confirmed block.
Operators:
Logical Operators:
&&
(and)||
(or)!
(not)
Comparison Operators:
==
,!=
<
,>
<=
,>=
Null Checks:
variable != null
variable == null
Example Rule:
"create": "@newData.admin == @user.address"
This rule allows a create operation only if the admin field in the new state matches the user's wallet address.
Fields: Enforcing Data Structure
When storing data on-chain, you must define the fields and their data types explicitly.
Supported Data Types:
String
Address
Int
UInt
Bool
Add ?
after the type to make it optional, e.g., "UInt?"
.
Example Fields Definition:
"fields": {
"createdBy": "Address",
"text": "String",
"amount": "UInt",
"maxMembers": "UInt?"
}