Overview
Permissions are the most granular building blocks of the Enterprise Stack RBAC model. Each protected operation on a resource is tied to a specific permission, enabling fine-grained control across different levels of the system.
Two-Layer Permission Enforcement
The Enterprise Stack enforces permissions at two layers to ensure comprehensive security:
- Route-Level Authorization: When a request arrives at an API endpoint, the system checks whether the caller has the required permission for that operation.
- Persistence-Level Authorization: When data is read from or written to the database, the system applies additional permission checks to ensure the caller can access the specific resources.
This dual-layer approach ensures that even if a request passes the initial route check, it cannot access data the user is not authorized to see.
Permission Scope
Permissions are always assigned within a scope. Scopes define where permissions are effective, following a hierarchical structure:
| Scope | Description |
|---|---|
| Organization | Access across all tenants in an organization |
| Tenant | Access limited to one tenant |
| Sub-tenant | Access limited to nested tenant structures |
| Service | Access limited to a specific service instance |
Example: A permission granted at Tenant A level applies to Tenant A and all services within it, but not to Tenant B.
Permission Propagation
In the tree-structured resource hierarchy, permissions follow a top-down logic:
- When a permission is granted at a parent node (e.g., organization), it automatically propagates to all child nodes (tenants, services, resources)
- This allows administrators to manage access for many resources by setting a single rule at a high level
Allow and Deny Rules
The Enterprise Stack supports both allow and deny rules:
- Allow rules grant access to perform specific operations
- Deny rules explicitly revoke access, even if an allow rule exists
Deny always overrides allow. This ensures that restricted access to sensitive resources cannot be accidentally granted by higher-level permissions.
Permission Evaluation Logic
When a user attempts to access a resource, the system evaluates the "Effective Permission" using these steps:
- Does the user have a matching allow rule for this resource? If no → Denied
- Does the user have a matching deny rule for this resource? If yes → Denied
- If allowed but not denied → Granted
Wildcards
ALL- Grants all permissions under the specified scope. Use with caution and consider applying deny rules to restrict specific sensitive operations.
Assigning Permissions to Roles
Permissions are assigned to roles using the Roles API. See Creating Roles for detailed instructions.
Example: Create a role with issuer permissions
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{roleId}/roles-api/roles/create' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"name": "Issuer Operator",
"permissions": [
{
"target": "waltid.tenant1.issuer1",
"action": "issuer-credential-issue"
},
{
"target": "waltid.tenant1.issuer1",
"action": "issuer-session-view"
}
]
}'
Revoking Permissions (Deny Rules)
To deny a specific permission, add it with "operation": "REMOVE":
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{roleId}/roles-api/permissions/permissions/add-to-role' \
-H 'Authorization: Bearer {yourToken}' \
-H 'Content-Type: application/json' \
-d '{
"target": "waltid.tenant1",
"action": "delete-resource-recursive",
"operation": "REMOVE"
}'
This creates a deny rule that prevents users with this role from deleting resources recursively in the specified tenant, even if they have broader ALL permissions.
Finding Required Permissions
You can find the required permissions for API endpoints by visiting the Swagger documentation. In the description of each endpoint, look for the Operation field which indicates the specific permission needed.
