RBAC Model
The Enterprise Stack uses Role-Based Access Control (RBAC) to authorize access to APIs and administrative operations.
Core Concepts
RBAC in the Enterprise Stack is built around four core concepts:
| Concept | Description |
|---|---|
| Permissions | Individual operations that can be performed (e.g., issuer-credential-issue, list-keys) |
| Roles | Named collections of permissions that can be assigned to principals |
| Principals | Identities such as Accounts, API Keys, or external IAM users |
| Scopes | Organizational boundaries (organization, tenant, service) where permissions apply |
Principal → Role → Permissions → API Access
Permission Scope
Roles are always assigned within a scope. Scopes define where permissions are effective and follow 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 |
Hierarchical Inheritance
Permissions propagate top-down through the resource hierarchy:
Organization (waltid)
│
├── Tenant A (waltid.tenantA)
│ ├── Issuer Service (waltid.tenantA.issuer1)
│ └── KMS Service (waltid.tenantA.kms1)
│
└── Tenant B (waltid.tenantB)
└── Verifier Service (waltid.tenantB.verifier1)
A permission granted at waltid (organization level) automatically applies to all resources below it. A permission granted at waltid.tenantA applies only to Tenant A and its services.
Allow and Deny Rules
Allow Rules (ADD)
Grant permissions to perform specific operations:
{
"target": "waltid.tenantA",
"action": "issuer-credential-issue",
"operation": "ADD"
}
Deny Rules (REMOVE)
Explicitly revoke permissions, overriding any allow rules:
{
"target": "waltid.tenantA.issuer1",
"action": "issuer-credential-issue",
"operation": "REMOVE"
}
Deny always wins. Even if a user has ALL permissions at the organization level, a deny rule on a specific resource will block access to that operation.
User Types
The Enterprise Stack recognizes different user types with different permission models:
| User Type | Permission Model |
|---|---|
| Super Admin | Bypasses all permission checks (full access) |
| Regular User | Permissions evaluated via allow/deny trees |
| Anonymous User | No permissions granted (public endpoints only) |
Example Role Configurations
Organization Administrator
Full access to manage the entire organization:
{
"name": "Organization Admin",
"permissions": [
{
"target": "waltid",
"action": "all",
"operation": "ADD"
}
]
}
Tenant Administrator
Full access within a specific tenant:
{
"name": "Tenant A Admin",
"permissions": [
{
"target": "waltid.tenantA",
"action": "all",
"operation": "ADD"
}
]
}
Issuer Operator
Limited to issuing credentials with a specific issuer service:
{
"name": "Issuer Operator",
"permissions": [
{
"target": "waltid.tenantA.issuer1",
"action": "issuer-credential-issue",
"operation": "ADD"
},
{
"target": "waltid.tenantA.issuer1",
"action": "issuer-session-view",
"operation": "ADD"
}
]
}
Restricted Admin
Full access with specific operations blocked:
{
"name": "Restricted Admin",
"permissions": [
{
"target": "waltid.tenantA",
"action": "all",
"operation": "ADD"
},
{
"target": "waltid.tenantA",
"action": "delete-resource-recursive",
"operation": "REMOVE"
}
]
}
Auditor (Read-Only)
View-only access for compliance and monitoring:
{
"name": "Auditor",
"permissions": [
{
"target": "waltid",
"action": "view-events",
"operation": "ADD"
},
{
"target": "waltid",
"action": "view-resource-tree",
"operation": "ADD"
}
]
}
Authorization Flow Example
Scenario: User requests to issue a credential
- Authentication: User authenticates with account credentials
- Identity Resolution: System identifies user as
user@example.org - Role Loading: System loads assigned roles (e.g., "Issuer Operator")
- Permission Check:
- Required permission:
issuer-credential-issueonwaltid.tenantA.issuer1 - Check allow tree: Found match via role grant
- Check deny tree: No matching deny rule
- Required permission:
- Result: Request allowed, credential issued
If the user had a deny rule or no matching allow rule, the request would return 403 Forbidden.
Best Practices
- Principle of Least Privilege: Grant only the permissions necessary for each role
- Use Scopes Appropriately: Assign permissions at the narrowest scope needed
- Leverage Deny Rules: Use deny rules to create exceptions in broad permission grants
- Regular Audits: Review role assignments and permissions periodically
- Separate Duties: Create distinct roles for different responsibilities (issuing vs. verification)
Related
- Permissions - Complete list of available permissions
- Roles - How to create and manage roles
- Accounts - Managing user accounts
- API Keys - Machine-to-machine authentication
- Super Admin - Unrestricted administrative access
- IAM Integration - External identity provider integration
