Skip to content
Resources & Permissions

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 catalog
  • orders — customer purchase transactions
  • users — 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:

ResourcePurpose
usersManaging project users
rolesManaging project roles
resourcesManaging project resources
permissionsManaging project permissions
clientsManaging project clients
Built-in resources are reserved by Roled and cannot be renamed or deleted. Think of these built-in resources as your own application’s resources for user and role management, similar to how you create 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_code

Examples:

products:create
products:read
products:update
products:delete

orders:read
orders:update

users:create
users:read
users:update
users:delete

The 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:

PermissionDescription
projects:readGet current project information
users:createCreate new users in the project
users:readList and view users
users:updateUpdate user data
users:deleteRemove users
roles:createCreate new roles
roles:readList and view roles
roles:updateUpdate role permissions
roles:deleteRemove roles
resources:createAdd new resources
resources:readList and view resources
resources:updateUpdate resource definitions
resources:deleteRemove resources
clients:createCreate new clients
clients:readList and view clients
clients:updateUpdate client data
clients:deleteRemove 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:

  1. Validates the JWT signature and expiry.
  2. Looks up the access token record in the database.
  3. Resolves the effective permissions of the authenticated identity (e.g., Alice Smith via Store Manager role).
  4. 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:action format.
  • 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.