Roles & Permissions
Document ID: ACP-001.2 Version: 1.0 Classification: Internal / Regulator-Shareable Effective Date: March 2026 Next Review: September 2026 Parent Document: ACP-001 — Access Control & Permissions
1. Overview
Keshless implements a Role-Based Access Control (RBAC) system with two parallel permission hierarchies:
- Admin Permissions — 9 role templates with 90+ granular permissions for dashboard employees
- Vendor Permissions — 5 role templates with 27 granular permissions for vendor staff
Both systems follow the principle of least privilege: all roles default to the minimum required permissions, and the CUSTOM role starts with zero permissions.
2. Base User Roles
The system defines three base roles stored as the UserRole enum:
| Role | Description | Access Scope |
|---|---|---|
USER | End user (wallet holder) | Own wallet, transactions, profile via mobile app |
ADMIN | General administrator | Dashboard access with assigned permissions |
SUPER_ADMIN | Super administrator | Unrestricted access to all system functions |
3. Admin Employee Roles
3.1 Role Hierarchy
Admin employees are assigned one of 9 specialized roles, each with a default permission template:
SUPER_ADMIN (unrestricted — all 90+ permissions)
│
├── ADMIN (all permissions except admin user management)
│
├── FINANCE_MANAGER (18 permissions — financial operations)
│
├── COMPLIANCE_OFFICER (13 permissions — AML/KYC focused)
│
├── SUPPORT_AGENT (10 permissions — read-only customer support)
│
├── AUDITOR (16 permissions — read-only across all areas)
│
├── SERVICE_CENTER_MANAGER (full SC ops + staff management)
│
├── SERVICE_CENTER_AGENT (basic SC operations only)
│
└── CUSTOM (empty — individually assigned permissions)3.2 Role Descriptions
| Role | Purpose | Key Capabilities | Key Restrictions |
|---|---|---|---|
| SUPER_ADMIN | Platform owner/CTO | All permissions; create/manage admin users; emergency controls | None |
| ADMIN | General administrator | All operational permissions | Cannot create/manage admin users or admin permissions |
| SUPPORT_AGENT | Customer support staff | View users, vendors, transactions, verifications, AML alerts | Read-only; cannot modify, approve, or delete anything |
| COMPLIANCE_OFFICER | AML/KYC compliance | View/manage AML alerts, file SARs, manage AML rules, view risk profiles, verify identities | Cannot modify financial configs, fees, or system settings |
| FINANCE_MANAGER | Financial operations | Process/approve withdrawals, view all transactions, manage fees/limits, export data | Cannot manage AML rules, create admin users, or manage emergencies |
| AUDITOR | Compliance auditing | Read-only access across users, vendors, transactions, verifications, AML, reports, audit logs | Strictly read-only; cannot modify any data |
| SERVICE_CENTER_MANAGER | Service center head | All SC operations, manage SC staff, view users/vendors | Bound to assigned service center; cannot access other SCs |
| SERVICE_CENTER_AGENT | Service center frontline | Vendor/user topups, card linking, withdrawals | Cannot manage staff, view reports, or access admin functions |
| CUSTOM | Flexible role | Any combination of individual permissions | Only has explicitly assigned permissions |
3.3 SUPER_ADMIN Privilege
SUPER_ADMIN has a special property in the permission system: all permission checks automatically return true, regardless of the explicit permissions list. This is enforced in both:
- Backend:
requireAdminPermission()middleware checksadminRole === 'SUPER_ADMIN'first - Frontend:
useAdminPermissions()hook returnstrueforisSuperAdminon everyhasPermission()call
4. Admin Permission Matrix
4.1 Permission Categories
All 90+ admin permissions are organized into 11 functional categories:
User Management (6 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_USERS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — |
EDIT_USERS | ✓ | ✓ | — | — | — | — | — | — |
BLOCK_USERS | ✓ | ✓ | — | — | — | — | — | — |
DELETE_USERS | ✓ | ✓ | — | — | — | — | — | — |
MANAGE_USER_WALLETS | ✓ | ✓ | — | — | ✓ | — | — | — |
VIEW_USER_TRANSACTIONS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — |
Vendor Management (7 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_VENDORS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — |
EDIT_VENDORS | ✓ | ✓ | — | — | — | — | — | — |
APPROVE_VENDORS | ✓ | ✓ | — | — | — | — | — | — |
BLOCK_VENDORS | ✓ | ✓ | — | — | — | — | — | — |
DELETE_VENDORS | ✓ | ✓ | — | — | — | — | — | — |
VIEW_VENDOR_TRANSACTIONS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — |
TOPUP_VENDORS | ✓ | ✓ | — | — | ✓ | — | — | — |
Admin User Management (5 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_ADMIN_USERS | ✓ | — | — | — | — | — | — | — |
CREATE_ADMIN_USERS | ✓ | — | — | — | — | — | — | — |
EDIT_ADMIN_USERS | ✓ | — | — | — | — | — | — | — |
DELETE_ADMIN_USERS | ✓ | — | — | — | — | — | — | — |
MANAGE_ADMIN_PERMISSIONS | ✓ | — | — | — | — | — | — | — |
Segregation of Duties: Only SUPER_ADMIN can create, edit, or delete other admin accounts. This prevents privilege escalation by lower-tier admins.
Card Management (4 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_CARDS | ✓ | ✓ | ✓ | — | ✓ | ✓ | — | — |
ISSUE_CARDS | ✓ | ✓ | — | — | — | — | — | — |
BLOCK_CARDS | ✓ | ✓ | — | — | — | — | — | — |
MANAGE_CARD_OPERATIONS | ✓ | ✓ | — | — | — | — | — | — |
Transaction Management (5 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_ALL_TRANSACTIONS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — |
PROCESS_WITHDRAWALS | ✓ | ✓ | — | — | ✓ | — | — | — |
APPROVE_WITHDRAWALS | ✓ | ✓ | — | — | ✓ | — | — | — |
REVERSE_TRANSACTIONS | ✓ | ✓ | — | — | ✓ | — | — | — |
MANUAL_ADJUSTMENTS | ✓ | ✓ | — | — | ✓ | — | — | — |
AML/Compliance (6 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_AML_ALERTS | ✓ | ✓ | ✓ | ✓ | — | ✓ | — | — |
MANAGE_AML_ALERTS | ✓ | ✓ | — | ✓ | — | — | — | — |
FILE_SAR | ✓ | ✓ | — | ✓ | — | — | — | — |
MANAGE_AML_RULES | ✓ | ✓ | — | ✓ | — | — | — | — |
VIEW_RISK_PROFILES | ✓ | ✓ | — | ✓ | — | ✓ | — | — |
MANAGE_EMERGENCY_CONTROLS | ✓ | ✓ | — | — | — | — | — | — |
System Configuration (5 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_SYSTEM_CONFIG | ✓ | ✓ | — | — | ✓ | ✓ | — | — |
MANAGE_FEES | ✓ | ✓ | — | — | ✓ | — | — | — |
MANAGE_LIMITS | ✓ | ✓ | — | — | ✓ | — | — | — |
MANAGE_SYSTEM_EMERGENCY | ✓ | ✓ | — | — | — | — | — | — |
VIEW_FEES_EARNINGS | ✓ | ✓ | — | — | ✓ | ✓ | — | — |
Reports & Analytics (3 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_REPORTS | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — |
VIEW_ANALYTICS | ✓ | ✓ | — | — | ✓ | ✓ | — | — |
EXPORT_DATA | ✓ | ✓ | — | — | ✓ | ✓ | — | — |
Verification (3 permissions)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_VERIFICATIONS | ✓ | ✓ | ✓ | ✓ | — | ✓ | — | — |
APPROVE_VERIFICATIONS | ✓ | ✓ | — | ✓ | — | — | — | — |
REJECT_VERIFICATIONS | ✓ | ✓ | — | ✓ | — | — | — | — |
Audit (1 permission)
| Permission | SUPER_ADMIN | ADMIN | SUPPORT | COMPLIANCE | FINANCE | AUDITOR | SC_MANAGER | SC_AGENT |
|---|---|---|---|---|---|---|---|---|
VIEW_AUDIT_LOGS | ✓ | ✓ | — | ✓ | ✓ | ✓ | — | — |
Service Center Operations (22 permissions)
| Permission | SC_MANAGER | SC_AGENT | Other Roles |
|---|---|---|---|
SC_VIEW_CENTER_BALANCE | ✓ | ✓ | — |
SC_VIEW_CENTER_TRANSACTIONS | ✓ | ✓ | — |
SC_VIEW_CENTER_STATS | ✓ | — | — |
SC_RECORD_CASH_DEPOSIT | ✓ | ✓ | — |
SC_TOPUP_VENDOR | ✓ | ✓ | — |
SC_VIEW_VENDOR_BALANCE | ✓ | ✓ | — |
SC_TOPUP_USER | ✓ | ✓ | — |
SC_WITHDRAW_USER | ✓ | ✓ | — |
SC_LINK_USER_CARD | ✓ | ✓ | — |
SC_RESET_USER_PIN | ✓ | ✓ | — |
SC_BLOCK_USER_CARD | ✓ | ✓ | — |
SC_UNBLOCK_USER_CARD | ✓ | ✓ | — |
SC_VERIFY_USER_KYC | ✓ | ✓ | — |
SC_MANAGE_STAFF | ✓ | — | — |
SC_CREATE_AGENT | ✓ | — | — |
SC_EDIT_AGENT | ✓ | — | — |
SC_DEACTIVATE_AGENT | ✓ | — | — |
SC_RESET_AGENT_PASSWORD | ✓ | — | — |
SC_SET_AGENT_LIMITS | ✓ | — | — |
SC_VIEW_AGENT_ACTIVITY | ✓ | — | — |
SC_APPROVE_TRANSACTIONS | ✓ | — | — |
Service Center Isolation: SC staff can only access data for their assigned service center. The
serviceCenterIdis bound to the admin employee record and enforced byrequireServiceCenterStaff()middleware.
5. Vendor Permission System
5.1 Vendor Role Templates
| Role | Purpose | Default Permissions |
|---|---|---|
| owner | Vendor owner/admin | All 27 permissions |
| manager | Store manager | 19 permissions (transactions, sub-users, terminal, no financial reports) |
| cashier | Point-of-sale staff | 13 permissions (create transactions, topups, card ops) |
| accountant | Finance/reporting | 5 permissions (read-only: transactions, balance, reports, earnings) |
| custom | Flexible role | Individually assigned permissions |
5.2 Vendor Permission Matrix
| Permission | owner | manager | cashier | accountant |
|---|---|---|---|---|
view_all_transactions | ✓ | ✓ | — | ✓ |
view_own_transactions | ✓ | ✓ | ✓ | ✓ |
create_transaction | ✓ | ✓ | ✓ | — |
refund_transaction | ✓ | ✓ | — | — |
view_balance | ✓ | ✓ | — | ✓ |
view_reports | ✓ | ✓ | — | ✓ |
manage_wallet | ✓ | ✓ | — | — |
withdraw_funds | ✓ | ✓ | — | — |
manage_sub_users | ✓ | ✓ | — | — |
view_sub_users | ✓ | ✓ | — | — |
update_vendor_profile | ✓ | ✓ | — | — |
view_vendor_profile | ✓ | ✓ | ✓ | ✓ |
manage_documents | ✓ | ✓ | — | — |
manage_terminal | ✓ | ✓ | ✓ | — |
accept_payments | ✓ | ✓ | ✓ | — |
short_onboard_customer | ✓ | ✓ | ✓ | — |
view_customers | ✓ | ✓ | ✓ | — |
manage_customers | ✓ | ✓ | — | — |
link_card | ✓ | ✓ | ✓ | — |
unlink_card | ✓ | ✓ | ✓ | — |
reset_pin | ✓ | ✓ | ✓ | — |
block_card | ✓ | ✓ | ✓ | — |
unblock_card | ✓ | ✓ | ✓ | — |
topup_user | ✓ | ✓ | ✓ | — |
withdraw_user | ✓ | ✓ | ✓ | — |
view_earnings | ✓ | ✓ | — | ✓ |
5.3 Vendor Owner Privilege
Similar to SUPER_ADMIN for admins, the vendor owner (main vendor account, not a sub-user) automatically has all vendor permissions. The requireVendorOwner() middleware specifically checks that the request comes from the main vendor account rather than a sub-user.
6. Permission Enforcement Mechanisms
6.1 Backend Middleware Stack
| Middleware | File | Purpose |
|---|---|---|
authMiddleware(allowedRoles?) | auth.middleware.ts | Validates JWT; optionally checks base role |
adminOnly() | auth.middleware.ts | Requires ADMIN or SUPER_ADMIN role |
requireAdminPermission(perm) | adminPermission.middleware.ts | Checks single admin permission |
requireAllAdminPermissions(perms) | adminPermission.middleware.ts | Checks ALL specified permissions |
requireSuperAdmin() | adminPermission.middleware.ts | SUPER_ADMIN only |
requireVendorOwner() | vendorPermission.middleware.ts | Main vendor account only |
requireVendorPermission(perm) | vendorPermission.middleware.ts | Checks single vendor permission |
requireVendorPermissions(perms) | vendorPermission.middleware.ts | Checks ALL vendor permissions |
requireAnyVendorPermission(perms) | vendorPermission.middleware.ts | Checks ANY vendor permission |
requireOwnVendor() | vendorPermission.middleware.ts | Can only access own vendor data |
checkOwnershipOrAdmin(param) | ownership.middleware.ts | User owns resource OR is admin |
requireServiceCenterStaff() | serviceCenter.middleware.ts | Must be assigned to active SC |
6.2 Mixed Access Middleware
The mixedAccess middleware allows flexible access rules where a request succeeds if any of the following conditions are met:
- User is SUPER_ADMIN
- Admin employee has the specified permission(s)
- Vendor owner (has all vendor permissions)
- Vendor sub-user has the specified permission(s)
- User is accessing their own resource (if enabled)
6.3 Frontend Permission Enforcement
Dashboard Components:
| Component | File | Purpose |
|---|---|---|
ProtectedRoute | ProtectedRoute.tsx | Route-level auth + optional permission check |
PermissionGate | PermissionGate.tsx | Component-level permission check |
useAdminPermissions() | useAdminPermissions.ts | Permission checking hook |
Hook API:
hasPermission(permission) — Check single permission
hasAnyPermission(permissions) — Check ANY match
hasAllPermissions(permissions) — Check ALL match
isSuperAdmin — Boolean flag
adminRole — Current role
adminPermissions — Full permission array
canCreateAdminUsers — Convenience (SUPER_ADMIN only)
canManageAdminPermissions — Convenience
canViewAdminUsers — Convenience
canEditAdminUsers — Convenience
canDeleteAdminUsers — ConvenienceSidebar Filtering: Menu items include an optional permission field. The sidebar automatically hides items the current user lacks permission to access.
Home Redirect Logic: After login, users are redirected to the first page they have permission to access:
- Service center staff →
/my-center - Has
VIEW_ANALYTICS→ Dashboard - Otherwise → first permitted route from verifications, transactions, users, vendors, cards, AML, reports, audit, admin, service centers
- Fallback →
/settings
7. USSD Operation Permissions
USSD operations are permission-gated by PIN verification rather than RBAC:
7.1 User Operations
| Menu | Operation | Requires PIN | Vendor Only |
|---|---|---|---|
| 1 | Check Balance | ✓ | — |
| 2 | Send Money | ✓ | — |
| 3 | Withdraw Cash | ✓ | — |
| 4 | Buy Airtime | ✓ | — |
| 5 | Pay Bill | ✓ | — |
| 6 | Mini Statement | — | — |
| 7.1 | Change PIN | ✓ (current PIN) | — |
| 7.2 | My Details | ✓ | — |
| 7.3 | Block Account | ✓ | — |
7.2 Vendor Operations (Menu 8)
| Sub-Menu | Operation | Requires Vendor PIN |
|---|---|---|
| 8.1 | Check Business Balance | ✓ |
| 8.2 | Topup Customer | ✓ |
| 8.3 | Process Withdrawal | ✓ |
| 8.4 | Business Mini Statement | ✓ |
Vendor Detection: On first USSD request, the server checks if the phone number is associated with a vendor account. If yes, Menu 8 ("Business") is shown. This check happens once per session.