Overview
Agatabo uses role-based access control (RBAC) to manage who can perform what actions. Permissions are granted through roles, which are assigned to organization users.Key features:
- Roles are organization-specific (each organization defines its own roles)
- Users can have multiple roles simultaneously
- Permissions are cumulative (union of all assigned roles)
- ANY scope takes precedence over SELF scope when same permission granted multiple times
Key Concepts
Permissions
A permission is the ability to perform a specific action on a resource. Format:resource:action
Examples:
savings:write- Record deposits and withdrawalsloans:read- View loan detailsexpenses:write- Record expensesaudit_logs:read- View audit trail
Scopes
Each permission has a scope that determines what data you can access:| Scope | Access Level | Example |
|---|---|---|
| SELF | Only your own data | View your own savings balance |
| ANY | All organization data | View all members’ savings balances |
savings:readwith SELF scope: Can only view own savings balancesavings:readwith ANY scope: Can view all members’ savings balancesloans:writewith SELF scope: Can only apply for loans for yourselfloans:writewith ANY scope: Can create loans for any member
- If user has same permission with different scopes (from multiple roles), ANY scope takes precedence
- Example: User has
savings:readwith SELF from “Member” role +savings:readwith ANY from “Treasurer” role = user gets ANY scope access
Roles
A role is a collection of permissions assigned to a user. Roles are organization-specific:- Each organization defines its own roles
- Role names and permissions configured by administrators
- No global/predefined roles in the system
- admin: Protected role, cannot be directly assigned/unassigned (must use set-admin endpoint)
- member: When assigned, automatically creates a savings ledger account for the user
key: Unique identifier (e.g., “treasurer”, “loan-officer”)name: Display name (e.g., “Treasurer”, “Loan Officer”)description: Optional description of role purposeisProtected: If true, role cannot be deletedisEditable: If true, role metadata and grants can be modifiedtagColor: UI color tag (SLATE, RED, BLUE, GREEN, etc.)
Complete Permission List
Organization Users (organization_users):
organization_users:read- View member list and detailsorganization_users:write- Add, edit, remove membersorganization_user_roles:read- View role definitionsorganization_user_roles:write- Create, edit, delete role definitionsorganization_user_roles:assign- Assign/unassign roles to users
savings):
savings:read- View deposit/withdrawal historysavings:write- Record deposits and withdrawals
loans):
loans:read- View loan details and installment schedulesloans:write- Create new loans, record paymentsloans:modify- Modify existing loan termsloans:approve- Approve loan applications
bank_accounts):
bank_accounts:read- View bank account list and balancesbank_accounts:write- Create, update, delete bank accounts
expenses):
expenses:read- View expense historyexpenses:write- Record and categorize expenses
assets):
assets:read- View fixed asset registerassets:write- Add, modify, dispose assets
reserves):
reserves:read- View reserve balancesreserves:write- Allocate to and release from reserves
dividends):
dividends:read- View dividend pools and distributionsdividends:write- Create pools and distribute dividends
ledger):
ledger:read- View ledger accounts, journal entries, trial balanceledger:write- Post manual journal entries
reports):
reports:read- Access financial reports (balance sheet, profit & loss, etc.)
settings):
settings:read- View organization settingssettings:write- Modify organization settings
periods):
periods:close- Close accounting periods
audit_logs):
audit_logs:read- View audit trail (requires ANY scope)
API Endpoints
Get My Permissions
Retrieve your own permissions:List Role Definitions
Get all roles in organization:organization_user_roles:write
Response:
- Role metadata (key, name, description, colors, protection status)
- All permission grants for the role
- Count of users assigned this role
Create Role Definition
Create a new role:organization_user_roles:assign
Request body fields:
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Unique role identifier (lowercase, no spaces) |
name | string | Yes | Display name |
description | string | No | Role description |
isEditable | boolean | No | Can role be modified? (default: true) |
tagColor | string | No | UI color tag (default: “SLATE”) |
Update Role Definition
Update role metadata (name, description, etc.):organization_user_roles:assign
Validation:
- Role must exist in organization
- Role must have
isEditable: true(protected roles cannot be edited)
Update Role Grants
Replace all permissions for a role:organization_user_roles:assign
How it works:
- Deletes ALL existing grants for this role
- Creates new grants from request body
- Returns updated role with new grants
| Field | Type | Required | Description |
|---|---|---|---|
grants | array | Yes | Array of permission grants |
grants[].permissionKey | string | Yes | Permission key (e.g., “savings:read”) |
grants[].scope | enum | Yes | ”SELF” or “ANY” |
Delete Role Definition
Delete a role:organization_user_roles:assign
Validation:
- Role must exist in organization
- Role must NOT be protected (
isProtected: false)
- All role assignments deleted (users lose this role)
- All permission grants deleted
- Role definition deleted
Assign Role to User
Grant a role to organization user:organization_user_roles:assign
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
roleDefinitionId | string | Yes | ID of role to assign |
assignedAt | string (ISO date) | No | Assignment date (defaults to now) |
- admin role: Cannot assign directly. Use set-admin endpoint instead.
- member role: Automatically creates savings ledger account for user
| Status | Message | Cause |
|---|---|---|
| 400 | ”Organization user not found” | Invalid organizationUserId |
| 400 | ”Role definition not found” | Invalid roleDefinitionId |
| 403 | ”Direct admin assignment is not allowed. Use set-admin” | Trying to assign admin role |
Unassign Role from User
Remove a role from organization user:organization_user_roles:assign
Validation:
- Cannot unassign admin role directly (use set-admin endpoint)
Update Role Assignment Date
Change assignment date for a role:organization_user_roles:assign
Use case: Backdate role assignment to reflect historical effective date
Response: Updated assignment object
How Permissions Are Checked
When you perform an action in Agatabo:-
System verifies authentication:
- Valid access token required
- x-organization-id header required
-
System checks if you have required permission:
- Example: Recording deposit requires
savings:write - Permission checked against your effective grants (from all assigned roles)
- Example: Recording deposit requires
-
System checks scope:
- If endpoint specifies
requiredScope: "ANY", you must have ANY scope - If endpoint has
scopeParam, system validates you’re accessing your own data (SELF scope) or allows any data (ANY scope)
- If endpoint specifies
-
Action allowed or denied:
- ✓ Allowed: Action proceeds
- ✗ Denied: Error “Insufficient permissions” or “Permission scope denied”
userType: "system_admin" grants all permissions with ANY scope automatically.
Permission Guard Logic
From permission.guard.ts:Common Error Messages
| Error | Status | Meaning | Solution |
|---|---|---|---|
| ”Authorization header is required” | 401 | Missing or invalid access token | Login and include valid Bearer token |
| ”X-Organization-ID header is required” | 401 | Missing organization header | Include x-organization-id header |
| ”OrganizationUser not found for this organization” | 401 | User not member of organization | Verify organization ID, check membership |
| ”Insufficient permissions” | 403 | Lack required permission entirely | Ask administrator to grant permission |
| ”Insufficient permission scope” | 403 | Have permission with SELF, need ANY | Ask administrator to grant ANY scope |
| ”Permission scope denied” | 403 | Trying to access others’ data with SELF scope | Only access your own data, or request ANY scope |
| ”Protected role definitions cannot be deleted” | 403 | Trying to delete protected role | Cannot delete, use different role |
| ”Role definition is not editable” | 403 | Trying to modify non-editable role | Cannot modify, create new role instead |
| ”Direct admin assignment is not allowed. Use set-admin” | 403 | Trying to assign/unassign admin role | Use set-admin endpoint instead |
Example Role Configurations
These are examples. Actual roles are organization-defined.Administrator Role
Suggested permissions (all with ANY scope):organization_users:write- Manage membersorganization_user_roles:assign- Assign rolessavings:write- Record depositsloans:write,loans:modify,loans:approve- Full loan managementexpenses:write- Record expensesassets:write- Manage assetsreserves:write- Manage reservesdividends:write- Distribute dividendsbank_accounts:write- Manage bank accountsledger:write- Post journal entriessettings:write- Change settingsperiods:close- Close periodsaudit_logs:read- View activity logsreports:read- Access reports
Treasurer Role
Suggested permissions (all with ANY scope):organization_users:read- View memberssavings:write- Record deposits/withdrawalsexpenses:write- Record expensesbank_accounts:read- View bank accountsledger:read- View ledgerreports:read- View reports
Loan Officer Role
Suggested permissions (all with ANY scope):organization_users:read- View membersloans:write- Create and manage loansloans:modify- Modify loan termsloans:approve- Approve loanssavings:read- View savings (verify eligibility)reports:read- View reports
Accountant Role
Suggested permissions (all with ANY scope):savings:read- View deposit historyloans:read- View loan portfolioexpenses:read- View expensesassets:read- View asset registerreserves:read- View reserve balancesdividends:read- View dividend historybank_accounts:read- View bank accountsledger:read- Full ledger accessledger:write- Post adjustmentsreports:read- Access reports
Member Role
Suggested permissions (all with SELF scope):organization_users:read- View own profilesavings:read- View own savings balanceloans:read- View own loansledger:read- View own ledger account statement
Best Practices
Permission management guidelines:Principle of least privilege:
- ✅ Grant only permissions needed for job function
- ✅ Start with minimal permissions, add as needed
- ✅ Use SELF scope for member-facing roles
- ✅ Reserve ANY scope for staff with organization-wide responsibilities
- ✅ Create roles matching actual job functions
- ✅ Use descriptive role names (“Treasurer”, not “Role1”)
- ✅ Document role purpose in description field
- ✅ Use color tags for visual organization
- ✅ Limit number of roles (5-10 typical)
- ✅ Assign roles based on user’s responsibilities
- ✅ Users can have multiple roles (permissions cumulative)
- ✅ Backdate assignments if needed (assignedAt field)
- ✅ Review assignments quarterly
- ✅ Revoke roles promptly when responsibilities change
- ✅ Protect critical roles (isProtected: true)
- ✅ Limit who has
organization_user_roles:assign - ✅ Audit role changes regularly (check audit logs)
- ✅ Don’t create overly permissive “super user” roles
- ✅ Separate duties (accountant ≠ treasurer)
- ✅ Default to SELF scope for member roles
- ✅ Use ANY scope for operational staff (treasurers, loan officers)
- ✅ Remember ANY scope takes precedence when combined
- ✅ Test permissions after assignment (verify access)
- ✅ Document role structure in organization policies
- ✅ Keep written record of who has what roles and why
- ✅ Review role definitions annually (remove unused roles)
- ✅ Update role grants when new features added
- ✅ Train users on their permissions and limitations
Troubleshooting
Q: Can’t see expected menu or button in UI A: You lack required permission. Solution:- Identify what you’re trying to do
- Check required permission (see permission list above)
- Ask administrator to grant appropriate role
- Log out and back in (refreshes permissions)
- Verify menu/button now visible
Q: Error: “Insufficient permissions” A: You don’t have the required permission at all. Check:
- GET /me/permissions to see your current grants
- Identify missing permission
- Ask administrator to assign role with that permission
Q: Error: “Insufficient permission scope” A: You have permission with SELF scope, but endpoint requires ANY scope. Example: Viewing audit logs requires
audit_logs:read with ANY scope.
Solution: Ask administrator to grant permission with ANY scope.
Q: Error: “Permission scope denied” A: You have permission with SELF scope, but trying to access someone else’s data. Example: You have
savings:read with SELF scope, but tried to view another member’s savings.
Solutions:
- Only access your own data, OR
- Ask administrator to grant ANY scope
Q: Can view data but can’t edit A: You have
read permission but not write permission.
Example: Can view loans (loans:read) but can’t create them (need loans:write).
Solution: Request write permission for that resource.
Q: Administrator changed my role but I still can’t access feature A: Permissions cached in access token. Try:
- Log out completely
- Log back in (refreshes token with new permissions)
- Try action again
Q: How do I see my own permissions? A: Call GET /me/permissions endpoint:
Q: Can I assign myself permissions? A: Only if you have
organization_user_roles:assign permission. Cannot escalate beyond your own permissions.
Safety: System doesn’t prevent self-assignment. Organizations should limit who has assign permission.
Q: What happens when user has multiple roles? A: Permissions are cumulative (union of all roles). Example:
- Role A grants:
savings:read(SELF),loans:read(SELF) - Role B grants:
savings:read(ANY),expenses:write(ANY) - Effective grants:
savings:read(ANY),loans:read(SELF),expenses:write(ANY)
Q: How do I create a custom role? A: Use role management API endpoints:
- POST /role-definitions (create role)
- PUT /role-definitions//grants (add permissions)
- POST /organization-users//role-assignments (assign to users)
Related Topics
Member Roles
Role management guide
Permissions Matrix
Complete permission reference
Managing Members
Add and manage organization users
Audit Trail
Track role and permission changes