Permission Routes
Table of Contents
Get Role Permissions
Retrieve all permissions for a specific role.
- URL:
/permissions/:roleId - Method:
GET - Auth required: Yes (Admin role)
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| roleId | string | Yes | ID of the role |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tenant_Id | string | No | Filter by tenant ID (multi-tenant mode only) |
| collection | string | No | Filter permissions by collection name |
Success Response
- Code: 200 OK
- Content:
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"role_Id": "4a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"collection": "products",
"action": "read",
"fields": ["*"],
"conditions": {},
"createdAt": "2023-06-01T12:00:00Z",
"updatedAt": "2023-06-01T12:00:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"role_Id": "4a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"collection": "products",
"action": "create",
"fields": ["name", "description", "price", "category_id"],
"conditions": {},
"createdAt": "2023-06-01T12:00:00Z",
"updatedAt": "2023-06-01T12:00:00Z"
}
]
}Error Responses
-
Code: 401 Unauthorized
- Content:
{ "error": { "message": "Authentication required" } }
- Content:
-
Code: 403 Forbidden
- Content:
{ "error": { "message": "Insufficient permissions" } }
- Content:
-
Code: 404 Not Found
- Content:
{ "error": { "message": "Role not found" } }
- Content:
-
Code: 500 Internal Server Error
- Content:
{ "error": { "message": "Error retrieving permissions" } }
- Content:
Create Permission
Create a new permission for a role.
- URL:
/permissions - Method:
POST - Auth required: Yes (Admin role)
- Content-Type:
application/json
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| role_Id | string | Yes | ID of the role |
| collection | string | Yes | Collection name for this permission |
| action | string | Yes | Permission action (read, create, update, delete) |
| fields | array/string | No | Array of field names or "*" for all fields |
| conditions | object | No | Conditions that limit the scope of the permission |
| tenant_Id | string | No | Tenant ID (required in multi-tenant mode) |
Example:
{
"role_Id": "4a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"collection": "products",
"action": "read",
"fields": ["*"],
"conditions": {
"user_id": { "$CURRENT_USER": "id" }
},
"tenant_Id": "8a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c"
}Success Response
- Code: 201 Created
- Content:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"role_Id": "4a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"collection": "products",
"action": "read",
"fields": ["*"],
"conditions": {
"user_id": { "$CURRENT_USER": "id" }
},
"tenant_Id": "8a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"createdAt": "2023-06-01T12:00:00Z",
"updatedAt": "2023-06-01T12:00:00Z"
}
}Error Responses
-
Code: 400 Bad Request
- Content:
{ "error": { "message": "Invalid permission data" } }
- Content:
-
Code: 401 Unauthorized
- Content:
{ "error": { "message": "Authentication required" } }
- Content:
-
Code: 403 Forbidden
- Content:
{ "error": { "message": "Insufficient permissions" } }
- Content:
-
Code: 500 Internal Server Error
- Content:
{ "error": { "message": "Error creating permission" } }
- Content:
Update Permission
Update an existing permission.
- URL:
/permissions/:id - Method:
PATCH - Auth required: Yes (Admin role)
- Content-Type:
application/json
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Permission ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| action | string | No | Permission action (read, create, update, delete) |
| fields | array/string | No | Array of field names or "*" for all fields |
| conditions | object | No | Conditions that limit the scope of the permission |
Example:
{
"fields": ["id", "name", "price", "description"],
"conditions": {
"status": "active"
}
}Success Response
- Code: 200 OK
- Content:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"role_Id": "4a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"collection": "products",
"action": "read",
"fields": ["id", "name", "price", "description"],
"conditions": {
"status": "active"
},
"tenant_Id": "8a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"createdAt": "2023-06-01T12:00:00Z",
"updatedAt": "2023-06-01T13:30:00Z"
}
}Error Responses
-
Code: 400 Bad Request
- Content:
{ "error": { "message": "Invalid permission data" } }
- Content:
-
Code: 401 Unauthorized
- Content:
{ "error": { "message": "Authentication required" } }
- Content:
-
Code: 403 Forbidden
- Content:
{ "error": { "message": "Insufficient permissions" } }
- Content:
-
Code: 404 Not Found
- Content:
{ "error": { "message": "Permission not found" } }
- Content:
-
Code: 500 Internal Server Error
- Content:
{ "error": { "message": "Error updating permission" } }
- Content:
Delete Permission
Delete a permission.
- URL:
/permissions/:id - Method:
DELETE - Auth required: Yes (Admin role)
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Permission ID |
Success Response
- Code: 200 OK
- Content:
{
"message": "Permission deleted successfully"
}Error Responses
-
Code: 401 Unauthorized
- Content:
{ "error": { "message": "Authentication required" } }
- Content:
-
Code: 403 Forbidden
- Content:
{ "error": { "message": "Insufficient permissions" } }
- Content:
-
Code: 404 Not Found
- Content:
{ "error": { "message": "Permission not found" } }
- Content:
-
Code: 500 Internal Server Error
- Content:
{ "error": { "message": "Error deleting permission" } }
- Content:
Bulk Update Permissions
Update multiple permissions for a role in a single operation.
- URL:
/permissions/bulk/:roleId - Method:
POST - Auth required: Yes (Admin role)
- Content-Type:
application/json
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| roleId | string | Yes | ID of the role |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| tenant_Id | string | No | Tenant ID (required in multi-tenant mode) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| permissions | array | Yes | Array of permission objects |
Example:
{
"permissions": [
{
"collection": "products",
"action": "read",
"fields": ["*"],
"conditions": {}
},
{
"collection": "products",
"action": "create",
"fields": ["name", "description", "price", "category_id"],
"conditions": {}
},
{
"collection": "products",
"action": "update",
"fields": ["name", "description", "price"],
"conditions": {
"user_id": { "$CURRENT_USER": "id" }
}
},
{
"collection": "products",
"action": "delete",
"fields": [],
"conditions": {
"user_id": { "$CURRENT_USER": "id" }
}
}
]
}Success Response
- Code: 200 OK
- Content:
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"role_Id": "4a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"collection": "products",
"action": "read",
"fields": ["*"],
"conditions": {},
"tenant_Id": "8a7d1ed4-8d7f-44b3-8f5e-7e5f2d8a7d3c",
"createdAt": "2023-06-01T12:00:00Z",
"updatedAt": "2023-06-01T12:00:00Z"
}
// ... other permissions
],
"message": "Permissions updated successfully"
}Error Responses
-
Code: 400 Bad Request
- Content:
{ "error": { "message": "Invalid permissions data" } }
- Content:
-
Code: 401 Unauthorized
- Content:
{ "error": { "message": "Authentication required" } }
- Content:
-
Code: 403 Forbidden
- Content:
{ "error": { "message": "Insufficient permissions" } }
- Content:
-
Code: 404 Not Found
- Content:
{ "error": { "message": "Role not found" } }
- Content:
-
Code: 500 Internal Server Error
- Content:
{ "error": { "message": "Error updating permissions" } }
- Content:
Permission Structure
Actions
The following actions can be assigned as permissions:
read: Allows reading items from a collectioncreate: Allows creating new items in a collectionupdate: Allows updating existing items in a collectiondelete: Allows deleting items from a collection
Fields
The fields property controls which fields the role can access. BAASIX supports powerful wildcard patterns for field-level permissions.
Wildcard Patterns
| Pattern | Description | Example |
|---|---|---|
* | The collection's own/direct fields only — does not include relations | ["*"] |
relation.* | All fields of a specific relation (one level deep) | ["*", "author.*"] |
relation.*.* | A relation's fields plus its own relations (one level deeper) | ["*", "posts.*.*"] |
Pattern Matching Rules
- Each
*segment matches exactly one level.*= own fields;author.*= the author relation's direct fields (allowsauthor.namebut notauthor.role.name). - To go deeper, add another
.*per level:author.*.*allowsauthor.role.name(the author's relations, one level further). There is no**syntax — use repeated.\*segments. - Critical: a bare
*grants only the collection's own columns. Any relation you want returned must be named explicitly (e.g."author.*"). A relation not listed infieldsis omitted from the response entirely, even ifrelConditionstargets it.
Examples
-
All fields access:
{ "fields": ["*"] }Allows access to the collection's own/direct fields only. This does not include any relations — to return a relation, add it explicitly (e.g.
["*", "author.*"]). -
Specific fields only:
{ "fields": ["id", "name", "email", "status"] }Allows access only to the specified fields.
-
All fields plus one relation:
{ "fields": ["*", "author.*"] }Allows access to all direct fields plus all fields of the
authorrelation. -
All fields plus nested relations (one level):
{ "fields": ["*", "author.*", "category.*"] }Allows access to all direct fields plus all fields of
authorandcategoryrelations. -
Full relation tree access:
{ "fields": ["*", "posts.*.*"] }Allows access to all direct fields plus the entire
postsrelation tree (posts, posts.comments, posts.comments.author, etc.) -
Mixed specific and wildcard:
{ "fields": ["id", "title", "author.name", "author.email", "category.*"] }Allows access to specific fields from the main collection, specific fields from
author, and all fields fromcategory. -
Restricted sensitive data:
{ "fields": ["id", "name", "email", "author.id", "author.name"] }Allows access to specific fields only - useful for hiding sensitive data like passwords, internal IDs, etc.
Conditions
The conditions property limits the scope of the permission using filtering expressions. This applies to the main collection being queried — it decides which records of this collection the role can access.
conditionsvsrelConditions:conditionsfilters the main records (which rows of this collection appear).relConditionsfilters the related rows returned inside array relations (which child rows appear in the response). They are not interchangeable — "which rows of this collection?" →conditions; "which related rows in the response?" →relConditions.
{
"status": "active" // Only items where status is "active"
}{
"department_id": { "$CURRENT_USER": "department.id" } // Only items in user's department
}{
"created_by": { "$CURRENT_USER": "id" } // Only items created by the current user
}Relational Conditions (relConditions)
The relConditions property is a deep filter for filtering within relations that return arrays. When a permission includes O2M (One-to-Many) or M2M (Many-to-Many) relations, those return as arrays. The relConditions filters what items appear in those arrays. It is keyed by relation name and does not restrict the main records.
Note: The property is always relConditions (plural).
Prerequisite: relConditions only takes effect on relations that are also granted in fields (e.g. "reviews.*"). If a relation isn't listed in fields, it's omitted from the response entirely and relConditions for it has no effect.
When to Use relConditions
| Relation Type | Returns | Use relConditions? |
|---|---|---|
| BelongsTo (N:1) | Single object | No |
| HasOne (1:1) | Single object | No |
| HasMany (O2M) | Array | ✅ Yes |
| BelongsToMany (M2M) | Array | ✅ Yes |
Examples
-
Filter comments array within posts:
{ "collection": "posts", "action": "read", "fields": ["*", "comments.*"], "relConditions": { "comments": { "isApproved": { "eq": true } } } }Users can read posts, but each post's
commentsarray only contains approved comments. -
Filter roles array for users (M2M):
{ "collection": "users", "action": "read", "fields": ["*", "roles.*"], "relConditions": { "roles": { "status": { "eq": "active" } } } }Each user's
rolesarray only contains active roles. -
Dynamic variables in relConditions:
{ "collection": "projects", "action": "read", "fields": ["*", "tasks.*"], "relConditions": { "tasks": { "assignedTo": { "eq": "$CURRENT_USER" } } } }Users can see all projects, but each project's
tasksarray only contains tasks assigned to them. -
Nested relConditions (array within array):
{ "collection": "organizations", "action": "read", "fields": ["*", "departments.*", "departments.employees.*"], "relConditions": { "departments": { "status": { "eq": "active" }, "employees": { "status": { "eq": "active" } } } } }Each organization's
departmentsarray contains only active departments, and each department'semployeesarray contains only active employees.
Combining conditions and relConditions
You can use both conditions (to filter main records) and relConditions (to filter related records) together:
{
"collection": "posts",
"action": "read",
"fields": ["*", "comments.*"],
"conditions": {
"status": "published"
},
"relConditions": {
"comments": {
"isApproved": { "eq": true }
}
}
}This permission allows reading only published posts, and for those posts, only approved comments are loaded.
Dynamic Variables
Permissions support dynamic variables that reference properties of the current user, role, tenant, or settings:
$CURRENT_USER: The ID of the authenticated user$CURRENT_USER.field: Any field of the user (e.g.,$CURRENT_USER.email,$CURRENT_USER.department)$CURRENT_ROLE: The ID of the current role$CURRENT_ROLE.field: Any field of the role$CURRENT_TENANT: The ID of the current tenant (multi-tenant)$CURRENT_TENANT.field: Any field of the tenant (e.g.,$CURRENT_TENANT.name)$CURRENT_SETTINGS.field: Any settings field, tenant-aware (e.g.,$CURRENT_SETTINGS.currency,$CURRENT_SETTINGS.language)$NOW: Current timestamp$NOW+DAYS_7,$NOW-HOURS_2, etc.: Relative date calculations
Related Documentation
Data Access
- Item Routes - Permission-controlled data access
- Schema Routes - Schema-level permissions
- Schema Reference Guide - Field types and data models
Query System
- Complete Filter Reference - Dynamic variables in permission conditions ($CURRENT_USER, $CURRENT_TENANT, $CURRENT_SETTINGS)
- Advanced Query Guide - Permission-filtered queries
Authentication
- Authentication Routes - User authentication and roles
Multi-tenant
- Multi-tenant Guide - Tenant-specific permissions and isolation
Automation
- Hooks System - Permission-related hooks
Reference
- API Routes Reference - Complete endpoint listing
- Integration Guide - Permission-aware client implementation