Resources & Permissions
Resources are the things you want to protect in your application. Permissions define the actions that can be performed on those resources. Together, they form the foundation of Roled’s access control model.
What Is a Resource?
A resource represents an entity in your application that you want to protect. Examples include:
products— items in the store catalogorders— customer purchase transactionsusers— staff accounts (built-in resource)roles— role definitions (built-in resource)
Resources are defined per project. When you create a project, Roled automatically creates several built-in resources:
| Resource | Purpose |
|---|---|
users | Managing project users |
roles | Managing project roles |
resources | Managing project resources |
permissions | Managing project permissions |
clients | Managing project clients |
products or orders resources for your application.What Is a Permission?
A permission defines a specific action that can be performed on a resource. Roled uses a simple resource:action format:
resource_code:permission_codeExamples:
products:create
products:read
products:update
products:delete
orders:read
orders:update
users:create
users:read
users:update
users:deleteThe resource_code and permission_code are machine-readable identifiers you define when creating resources and permissions.
Resource and Permission Structure
graph TD
Resource["Resource: products"] --> P1["Permission: products:create"]
Resource --> P2["Permission: products:read"]
Resource --> P3["Permission: products:update"]
Resource --> P4["Permission: products:delete"]
Each resource can have multiple permissions. You define both the resource and its permissions together.
How Permissions Flow to Users and Clients
Permissions are not assigned directly to users. They flow through roles for users, and are assigned directly to clients:
graph LR
Perm["Permission: products:create"] --> Role["Role: Store Manager"]
Role --> User["User: Alice Smith"]
graph LR
Perm["Permission: orders:read"] --> Client["Client: Backend Service"]
- Users get permissions through their assigned role.
- Clients (machine identities) have permissions assigned directly.
Built-in Permissions
When a project is created, the built-in resources come pre-populated with standard CRUD permissions:
| Permission | Description |
|---|---|
projects:read | Get current project information |
users:create | Create new users in the project |
users:read | List and view users |
users:update | Update user data |
users:delete | Remove users |
roles:create | Create new roles |
roles:read | List and view roles |
roles:update | Update role permissions |
roles:delete | Remove roles |
resources:create | Add new resources |
resources:read | List and view resources |
resources:update | Update resource definitions |
resources:delete | Remove resources |
clients:create | Create new clients |
clients:read | List and view clients |
clients:update | Update client data |
clients:delete | Remove clients |
Creating a Resource with Permissions
Use the following request to create a new resource along with its permissions. Here we create the products resource with CRUD permissions:
curl --request POST \
--url https://auth.roled.id/api/v1/projects/2JUSLUee46xG6iEwG8JwPc/resources \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJo...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Products",
"code": "products",
"description": "Product catalog",
"permissions": [
{
"name": "Create",
"code": "create",
"description": "Create a new product in the catalog"
},
{
"name": "Read",
"code": "read",
"description": "List and view products"
},
{
"name": "Update",
"code": "update",
"description": "Update product information and stock levels"
},
{
"name": "Delete",
"code": "delete",
"description": "Remove products from the catalog"
}
]
}'Response:
{
"success": true,
"data": {
"id": "2JUUyotLU97ZghzqwrqE6o",
"created_at": "2026-07-16T14:30:00Z",
"updated_at": "2026-07-29T08:30:00Z",
"name": "Products",
"code": "products",
"description": "Product catalog",
"is_default": false,
"permissions": [
{
"id": "2JUUyotLUqz5eqsuYXXDet",
"name": "Create",
"code": "create",
"description": "Create a new product in the catalog",
"is_default": false
},
{
"id": "2JUUyotLUr7SuBqkzjRbTc",
"name": "Read",
"code": "read",
"description": "List and view products",
"is_default": false
},
{
"id": "2JUUyotLUrApxL7zcx7Xoy",
"name": "Update",
"code": "update",
"description": "Update product information and stock levels",
"is_default": false
},
{
"id": "2JUUyotLUrDfBK9iwe25jj",
"name": "Delete",
"code": "delete",
"description": "Remove products from the catalog",
"is_default": false
}
]
}
}Listing All Permissions in a Project
You can fetch all available permissions in a project to use when setting up roles or clients:
curl --request GET \
--url https://auth.roled.id/api/v1/projects/2JUSLUee46xG6iEwG8JwPc/permissions \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJo...'Permissions Are Evaluated Server-Side
A key design decision in Roled: permissions are never embedded in JWTs.
When a request comes in with a JWT, Roled:
- Validates the JWT signature and expiry.
- Looks up the access token record in the database.
- Resolves the effective permissions of the authenticated identity (e.g., Alice Smith via Store Manager role).
- Checks whether the required permission is present.
sequenceDiagram
autonumber
participant App as Your App
participant R as Roled API
participant DB as Database
App->>R: GET /api/v1/projects/{id}/users
note over R: Requires users:read permission
R->>R: Validate JWT signature & expiry
R->>DB: Look up access token record
DB-->>R: Token status & identity
R->>DB: Resolve permissions for identity
DB-->>R: ["users:read", "users:update"]
R->>R: "users:read" found
R-->>App: 200 OK — user list returned
This means permission changes take effect immediately — you do not have to wait for tokens to expire or be reissued.
Key Points
- Resources represent entities you want to protect (e.g.,
products,orders). - Permissions define actions on resources using the
resource:actionformat. - Built-in resources (
users,roles,resources,permissions,clients) are created automatically. - Permissions flow to users via roles, and to clients directly.
- Permissions are never stored in JWTs — they are always resolved server-side.