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:

  1. Route-Level Authorization: When a request arrives at an API endpoint, the system checks whether the caller has the required permission for that operation.
  2. 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:

ScopeDescription
OrganizationAccess across all tenants in an organization
TenantAccess limited to one tenant
Sub-tenantAccess limited to nested tenant structures
ServiceAccess 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:

  1. Does the user have a matching allow rule for this resource? If no → Denied
  2. Does the user have a matching deny rule for this resource? If yes → Denied
  3. 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.

Last updated on May 6, 2026