Permissions
Permissions define specific abilities in your application. Every permission follows the resource:action format and belongs to a single application. Permissions are attached to roles, and users inherit permissions through their assigned roles.
Permission Format
All permissions use the resource:action format:
posts:create
users:delete
reports:export
billing:view
Wildcards (*) are also valid in either position:
posts:* # all actions on posts
*:read # read action on any resource
*:* # all actions on all resources (full access)
See Wildcard Matching for full pattern rules.
Validation pattern: ^[a-zA-Z0-9_*-]+:[a-zA-Z0-9_*-]+$
Permissions are created automatically when you use them in a role. You do not need to pre-register them before attaching to a role.
Defining Permissions
Permissions are defined inline when creating or updating roles — there is no standalone permission creation endpoint in the V1 API. When you include a permission string in a role's permissions array, it is created automatically if it does not already exist.
{
"name": "editor",
"permissions": ["posts:create", "posts:edit", "reports:export"]
}
See the Roles API for how to create roles and assign permissions.
Full permission management (list, create, update, delete) is available via the Dashboard API at /api/dashboard/applications/{applicationId}/permissions. These endpoints use Sanctum cookie authentication and are intended for use by the YorAuth dashboard.
Check a Permission
The primary authorization check endpoint. Use this on your backend to gate any action.
GET /api/v1/applications/{applicationId}/authz/check
POST /api/v1/applications/{applicationId}/authz/check
Requires JWT scope: authz:check
Use GET for simple RBAC-only checks (pass parameters as query string). Use POST when you need to include resource or context attributes for ABAC policy evaluation.
RBAC-only check (GET)
curl -X GET \
"https://api.yorauth.com/api/v1/applications/your-application-id/authz/check?user_id=user-123&permission=posts:create" \
-H "Authorization: Bearer <jwt>"
Response 200 OK:
{
"allowed": true,
"permission": "posts:create",
"cached": true
}
The cached field indicates whether the result was served from Redis. A cached result typically adds under 5ms of latency.
RBAC + ABAC check (POST)
When you pass resource or context, the authorization engine runs RBAC first. If RBAC denies, it returns immediately. If RBAC allows, active ABAC policies for the permission are evaluated.
curl -X POST \
https://api.yorauth.com/api/v1/applications/your-application-id/authz/check \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user-123",
"permission": "posts:delete",
"resource": {
"owner_id": "user-123",
"status": "draft"
},
"context": {
"ip": "203.0.113.42"
}
}'
Response 200 OK (with ABAC):
{
"allowed": true,
"permission": "posts:delete",
"cached": false,
"abac_evaluated": true,
"policies_checked": 2
}
Request parameters:
| Parameter | Required | Description |
|---|---|---|
user_id | Yes | Your external user identifier |
permission | Yes | Permission string in resource:action format |
resource | No | Key-value map of resource attributes for ABAC |
context | No | Key-value map of context attributes for ABAC (IP, time, etc.) |
Response fields:
| Field | Description |
|---|---|
allowed | true if the user has the permission |
permission | The permission that was checked |
cached | Whether the RBAC result came from Redis cache |
abac_evaluated | Present when ABAC params provided; true if policies were evaluated |
policies_checked | Number of ABAC policies evaluated (present with ABAC params) |
Error responses:
422 Unprocessable Entity— Invalidpermissionformat (must matchresource:action)
Bulk Permission Check
Check up to 50 permissions for a user in a single request.
POST /api/v1/applications/{applicationId}/authz/check-bulk
Requires JWT scope: authz:check
The user's permission set is loaded once from cache and all checks are evaluated in memory — this is more efficient than making multiple single-check requests.
curl -X POST \
https://api.yorauth.com/api/v1/applications/your-application-id/authz/check-bulk \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user-123",
"permissions": [
"posts:create",
"posts:delete",
"users:invite",
"billing:view",
"reports:export"
]
}'
const response = await fetch(
'https://api.yorauth.com/api/v1/applications/your-application-id/authz/check-bulk',
{
method: 'POST',
headers: {
'Authorization': 'Bearer <jwt>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
user_id: 'user-123',
permissions: [
'posts:create',
'posts:delete',
'users:invite',
'billing:view',
'reports:export'
]
})
}
);
const { user_id, results } = await response.json();
Response 200 OK:
{
"user_id": "user-123",
"results": {
"posts:create": true,
"posts:delete": true,
"users:invite": false,
"billing:view": false,
"reports:export": true
}
}
Bulk check with ABAC
You can also pass resource and context to the bulk endpoint. When provided, each permission that passes RBAC is additionally evaluated through active ABAC policies. The result per permission is a boolean.
{
"user_id": "user-123",
"permissions": ["posts:delete", "posts:publish"],
"resource": { "owner_id": "user-123", "status": "draft" },
"context": { "ip": "203.0.113.42" }
}
Request parameters:
| Parameter | Required | Description |
|---|---|---|
user_id | Yes | Your external user identifier |
permissions | Yes | Array of 1–50 permission strings |
resource | No | Key-value map of resource attributes for ABAC |
context | No | Key-value map of context attributes for ABAC |
The bulk check uses a single Redis lookup to load the user's permission set, then evaluates all permissions in memory. Use it when you need to determine multiple access decisions at once — such as rendering a UI with enabled/disabled actions.
Caching Behaviour
Permission checks are backed by versioned Redis caching. The user's complete permission set (all permissions from all roles, including team-inherited ones) is cached for 1 hour.
When any of the following happen, the cache version is incremented, making all cached permission sets for the application immediately stale:
- A role is created, updated, or deleted
- A permission is assigned to or removed from a role
- A user's role assignment is added or revoked
On the next check after invalidation, the permission set is recomputed from the database and re-cached.
The cached field in a single-check response reflects whether the current check hit the cache or required a database query.