Roles & Permissions
ZB ID uses role-based access control (RBAC) to govern what each user can do across the platform. Users are assigned roles, roles contain permissions, and those permissions are embedded as scopes in JWT tokens issued during authentication.
RBAC overview
ZB ID implements a layered authorization model built on three concepts:
- Users are the individuals or service accounts that interact with the platform.
- Roles are named collections of permissions assigned to users. A user can hold multiple roles simultaneously.
- Permissions are fine-grained access controls that map directly to JWT scopes. When a token is issued, the user's permissions are included as scopes in the token payload.
This design allows downstream ZB services (banking, lending, insurance, wealth management) to make authorization decisions locally by inspecting the scopes on the JWT, without calling back to ZB ID on every request.
How it works
- An administrator assigns one or more roles to a user.
- When the user authenticates, ZB ID resolves all permissions from the assigned roles.
- Those permissions are embedded as
scopesin the issued JWT. - Downstream services check
scopesto authorize or deny access.
Scope-based authorization: Every permission listed below becomes a JWT scope. Services can verify access by checking whether the required scope is present in the token, either via local JWT validation or by calling the /oauth/introspect endpoint.
Default roles
ZB ID ships with six default roles. Each role comes pre-configured with a set of permissions appropriate for its intended use case.
| Role | Description |
|---|---|
| customer | End users of ZB digital products. Granted read and write access to their own profile, banking, lending, insurance, and wealth data. |
| merchant | Business operators who accept payments or provide services through ZB platforms. Includes banking read/write, lending read, and profile permissions. |
| staff | Internal ZB employees who manage day-to-day operations. Includes read access across product lines plus user management and KYC review. |
| admin | System administrators with full access, including user management, role assignment, KYC administration, audit logs, and platform configuration. |
| auditor | Compliance and audit personnel with read-only access across product lines plus access to audit logs. Cannot modify data or manage users. |
| driver | Delivery drivers. Granted profile:read and profile:write only. |
Custom roles can be created through the admin interface or the API to support more specialized access patterns.
Role inheritance: Roles do not inherit from one another. Each role defines its own independent set of permissions. If you need a role that combines permissions from multiple roles, create a custom role or assign multiple roles to the user.
Permissions
Permissions follow a resource:action naming convention. Each permission maps one-to-one with a JWT scope.
Product permissions
- Name
banking:read- Type
- scope
- Description
Read access to banking accounts, balances, and transaction history.
- Name
banking:write- Type
- scope
- Description
Create or modify banking resources such as accounts and transfers.
- Name
lending:read- Type
- scope
- Description
Read access to loan applications, balances, and repayment schedules.
- Name
lending:write- Type
- scope
- Description
Create or modify loan applications and repayment actions.
- Name
insurance:read- Type
- scope
- Description
Read access to insurance policies, claims, and coverage details.
- Name
insurance:write- Type
- scope
- Description
Create or modify insurance policies and submit claims.
- Name
wealth:read- Type
- scope
- Description
Read access to investment portfolios, fund balances, and performance data.
- Name
wealth:write- Type
- scope
- Description
Create or modify investment positions and portfolio allocations.
- Name
profile:read- Type
- scope
- Description
Read access to user profile information, contact details, and preferences.
- Name
profile:write- Type
- scope
- Description
Update user profile information and preferences.
Administrative permissions
- Name
admin:users- Type
- scope
- Description
Manage user accounts: create, update, suspend, or delete users.
- Name
admin:roles- Type
- scope
- Description
Manage role assignments: list, assign, and remove roles from users.
- Name
admin:audit- Type
- scope
- Description
Access audit logs and compliance reports.
- Name
admin:kyc- Type
- scope
- Description
Manage KYC verification workflows: review, approve, or reject submissions.
- Name
admin:config- Type
- scope
- Description
Modify platform-level configuration settings.
- Name
admin:clients- Type
- scope
- Description
Manage OAuth client applications: register, update, or revoke clients.
KYC permissions
These scopes are granted to OAuth clients (via the client credentials grant) that call the central KYC endpoints.
- Name
kyc:validate- Type
- scope
- Description
Validate national IDs against the e-Gov registry.
- Name
kyc:credit-check- Type
- scope
- Description
Run FCB credit bureau searches.
- Name
kyc:screen- Type
- scope
- Description
Run World-Check AML screening and read KYC verifications.
Example JWT scopes payload
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"iss": "https://id.zb.co.zw",
"scopes": [
"banking:read",
"banking:write",
"profile:read",
"profile:write"
],
"roles": ["merchant"],
"exp": 1717200000,
"iat": 1717113600
}
Checking permissions in your service: Parse the JWT and verify that the required scope is present in the scopes array before allowing the operation. For example, a banking transfer endpoint should require banking:write.
List user roles
Retrieve all roles currently assigned to a specific user. This endpoint is useful for building admin dashboards and for auditing user access.
Required headers
- Name
Authorization- Type
- string
- Description
Bearer token with the
admin:rolesscope.
Path parameters
- Name
userId- Type
- string
- Description
The unique identifier (UUID) of the user whose roles you want to list.
Request
curl https://id.zb.co.zw/users/550e8400-e29b-41d4-a716-446655440000/roles \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
Response
{
"result": "success",
"roles": [
{
"roleName": "merchant",
"subsidiaryScope": "zb-bank",
"assignedAt": "2026-03-15T10:30:00Z",
"assignedBy": "[email protected]"
},
{
"roleName": "customer",
"subsidiaryScope": null,
"assignedAt": "2026-01-10T08:00:00Z",
"assignedBy": "system"
}
]
}
Assign a role
Assign a role to a user. If the user already has the specified role, the request will return a conflict error.
Required headers
- Name
Authorization- Type
- string
- Description
Bearer token with the
admin:rolesscope.
- Name
Content-Type- Type
- string
- Description
Must be
application/json.
Path parameters
- Name
userId- Type
- string
- Description
The unique identifier (UUID) of the user to assign the role to.
Request body
- Name
roleName- Type
- string
- Description
The name of the role to assign (e.g.,
customer,merchant,staff,admin,auditor,driver, or a custom role name).
- Name
subsidiaryScope- Type
- string
- Description
Optional. Limits the role to a specific ZB subsidiary (e.g.,
zb-bank,zb-life,zb-reinsurance). When omitted, the role applies across all subsidiaries.
Request
curl -X POST https://id.zb.co.zw/users/550e8400-e29b-41d4-a716-446655440000/roles \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"roleName": "merchant",
"subsidiaryScope": "zb-bank"
}'
Response
{
"result": "success",
"message": "Role 'merchant' assigned to user successfully",
"role": {
"roleName": "merchant",
"subsidiaryScope": "zb-bank",
"assignedAt": "2026-05-31T14:20:00Z",
"assignedBy": "[email protected]"
}
}
Remove a role
Remove a role from a user. The user's active JWT tokens will continue to carry the old scopes until they expire or are refreshed. For immediate revocation, you should also invalidate the user's sessions.
Required headers
- Name
Authorization- Type
- string
- Description
Bearer token with the
admin:rolesscope.
Path parameters
- Name
userId- Type
- string
- Description
The unique identifier (UUID) of the user.
- Name
roleName- Type
- string
- Description
The name of the role to remove.
Request
curl -X DELETE https://id.zb.co.zw/users/550e8400-e29b-41d4-a716-446655440000/roles/merchant \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
Response
{
"result": "success",
"message": "Role 'merchant' removed from user"
}
Important: Removing a role does not immediately invalidate existing JWT tokens. The user will retain the old scopes until their token expires or they re-authenticate. To enforce immediate access revocation, invalidate the user's active sessions after removing the role.