Access Control List (ACL)
The Access Control List (ACL) defines the relationships between users, items, and actions. It determines which users are allowed to perform which actions on which items.
Default Behavior
Section titled “Default Behavior”- All users can view all events. This means that Simple Sync is only appropriate for situations where all users of the system can be trusted to view all data in the system.
- By default, a user cannot perform any action on any item unless explicitly allowed by an ACL rule (deny all by default).
- Note: there is a difference between viewing items and performing actions on items. All users can view all items because they can read all the events. However, they can not submit new events that perform actions on items without ACL rules to allow it.
- The
.rootuser has implicit access to all items and actions, bypassing ACL checks.
ACL Structure
Section titled “ACL Structure”ACL rules are tracked as events on a special .acl item with an .acl.addRule action. Each ACL rule has the following three fields, all of which must be non-empty strings:
useritemaction
Each field supports:
- Specific values (e.g., user ID, item ID, action name)
- Prefix wildcards (e.g.,
admin.*,task.*,edit.*) - Wildcard (
*) for all matches
ACL events are submitted via the dedicated POST /api/v1/acl endpoint, which automatically sets the current timestamp and ensures proper validation. ACL events submitted via POST /api/v1/events are rejected to prevent timestamp manipulation.
Wildcard Support
Section titled “Wildcard Support”The user, item, and action fields support the wildcard (*) to match all, and also support prefix-based wildcards (e.g., task.*, admin.*, edit.*) to match all that start with the specified prefix.
Rule Evaluation
Section titled “Rule Evaluation”ACL rules are evaluated based on specificity. For a given user, item, and action, the rule with the highest specificity score determines whether the action is allowed or denied. Specificity is calculated as the character count of the user, item, and action portions of a matching rule (wildcards are worth 0.5 specificity points).
- Item specificity takes first precedence.
- If there is a tie in item specificity, user specificity takes second precedence.
- If there is a tie in user specificity, action specificity takes third precedence.
- If there is still a tie, the most recently added rule (highest timestamp) takes precedence.
If no rule matches, the default behavior (deny all actions) applies.
Specificity Examples
Section titled “Specificity Examples”For a request by user user.123 to perform edit on item task.456:
| Rule | Item | User | Action | Item Score | User Score | Action Score |
|---|---|---|---|---|---|---|
| A | * | * | * | 0.5 | 0.5 | 0.5 |
| B | * | user.123 | * | 0.5 | 8 | 0.5 |
| C | task.* | * | * | 5.5 | 0.5 | 0.5 |
| D | * | * | edit | 0.5 | 0.5 | 4 |
Compare item specificity: Rule C (5.5) > others (0.5) → Rule C wins.
For item task.456 and action edit, assuming no higher item matches:
| Rule | Item | User | Action | Item Score | User Score | Action Score |
|---|---|---|---|---|---|---|
| E | task.* | * | edit | 5.5 | 0.5 | 4 |
| F | * | * | edit | 0.5 | 0.5 | 4 |
Item specificity: Rule E (5.5) > Rule F (0.5) → Rule E wins.
For item task.456, user admin.123, action edit, with item specificity tied:
| Rule | Item | User | Action | Item Score | User Score | Action Score |
|---|---|---|---|---|---|---|
| G | task.* | * | * | 5.5 | 0.5 | 0.5 |
| H | task.* | admin.* | * | 5.5 | 6.5 | 0.5 |
Item specificity tied (5.5), compare user: Rule H (6.5) > Rule G (0.5) → Rule H wins.
For item task.456, user admin.123, action edit.description, with item and user specificity tied:
| Rule | Item | User | Action | Item Score | User Score | Action Score |
|---|---|---|---|---|---|---|
| I | task.* | admin.* | * | 5.5 | 6.5 | 0.5 |
| J | task.* | admin.* | edit.* | 5.5 | 6.5 | 5.5 |
Item and user tied, compare action: Rule J (5.5) > Rule I (0.5) → Rule J wins.
Action Values
Section titled “Action Values”Action values in ACL rules can be any custom string that matches the actions your application uses. The examples below show common patterns, but you can use any action names that make sense for your use case (e.g., create, update, delete, publish, archive, or domain-specific actions like markComplete, assign, review).
Rule Examples
Section titled “Rule Examples”To allow all users to mark “task.123” as complete:
{ "uuid": "01997af2-df11-73b3-8329-e5c3affc9a05", "timestamp": 1758704361233, "user": "admin.user1", "item": ".acl", "action": ".acl.addRule", "payload": "{\"user\": \"*\", \"item\": \"task.123\", \"action\": \"markComplete\", \"type\": \"allow\"}"}To allow user “user.456” to edit any item:
{ "uuid": "01997af3-4299-7be7-8bd7-d01636e06d73", "timestamp": 1758704386713, "user": "admin.user1", "item": ".acl", "action": ".acl.addRule", "payload": "{\"user\": \"user.456\", \"item\": \"*\", \"action\": \"edit\", \"type\": \"allow\"}"}To allow all admin users to perform any delete action on any task:
{ "uuid": "01997af3-7a2f-7b65-9055-8439f87d7450", "timestamp": 1758704400943, "user": "admin.user1", "item": ".acl", "action": ".acl.addRule", "payload": "{\"user\": \"admin.*\", \"item\": \"task.*\", \"action\": \"delete.*\", \"type\": \"allow\"}"}ACL Management
Section titled “ACL Management”ACL rules are managed by submitting ACL rules to the dedicated POST /api/v1/acl endpoint.
ACL events submitted via POST /api/v1/events are rejected. The current ACL state can be inferred from the authoritative event history by filtering for .acl events. See the v1 API Specification for details on the dedicated ACL endpoint.
Note: ACL submission requires appropriate permissions based on existing rules. The .root user has implicit access to submit any ACL events.