Role-Based Authorization in ImPAI
ImPAI uses Keycloak as its identity and access management solution to implement role-based authorization. This approach ensures that users and applications only have access to the resources and operations they are authorized to use.
Role-Based Access Control (RBAC)β
Understanding RBACβ
Role-Based Access Control is a security approach that restricts system access to authorized users based on roles. In the ImPAI platform:
- Roles define a set of permissions and access levels
- Users are assigned one or more roles
- Resources (API endpoints, operations) are protected based on required roles
- Access decisions are made by verifying if a user has the required role(s)
Roles in ImPAIβ
ImPAI implements two types of roles in Keycloak:
Realm Rolesβ
Realm roles are global roles that apply across the entire ImPAI platform.
| Role Name | Description | Access Level |
|---|---|---|
| admin | Full administrative access | All operations and resources |
| user | Standard user access | Basic operations and resources |
| api-user | API access only | API endpoints with appropriate scopes |
| read-only | View-only access | Read operations only |
Client Rolesβ
Client roles are specific to particular applications or services within ImPAI.
| Client | Role Name | Description |
|---|---|---|
| payment-service | payment-initiator | Can initiate payments |
| payment-service | payment-approver | Can approve payments |
| account-service | account-viewer | Can view account information |
| account-service | account-manager | Can manage account settings |
Configuring Rolesβ
System administrators are responsible for creating and assigning ImPAI access roles within Keycloak. Use the following steps to complete the configuration:
- Access the Keycloak Admin Console
- Navigate to your Keycloak instance admin console
- Log in with administrator credentials
- Create and Manage Roles
- Select the appropriate realm
- Navigate to "Roles" in the left sidebar
- Use "Add Role" to create new roles
- Define role attributes and descriptions
- Assign Roles to Users
- Navigate to "Users" in the left sidebar
- Select a user and go to the "Role Mappings" tab
- Assign appropriate realm and client roles
- Configure Client Scopes
- Navigate to "Client Scopes" in the left sidebar
- Create or edit scopes to include role information in tokens
- Ensure the "roles" mapper is included
Implementing Role Checksβ
Developers must enforce role-based access in the application to ensure users can only perform actions allowed by their assigned roles.
Token Structureβ
ImPAI uses JWT tokens (JSON Web Tokens) to securely represent a userβs authenticated session.
A JWT contains digitally signed user identity and role information so the system can verify access rights without storing session data on the server.
When a user authenticates, the JWT access token will contain role information in the following format:
{
"exp": 1643235,
"iat": 1643234,
"auth_time": 1643233,
"jti": "4321-5678-abcd-efgh",
"iss": "https://auth.impai.com/realms/impai",
"sub": "1234567890",
"typ": "Bearer",
"realm_access": {
"roles": ["user", "api-user"]
},
"resource_access": {
"payment-service": {
"roles": ["payment-initiator"]
},
"account-service": {
"roles": ["account-viewer"]
}
},
"scope": "openid profile email"
}
Checking Roles in Your Applicationβ
To verify if a user has the required role:
- Extract the JWT token from the Authorization header.
- Decode and verify the token.
- Check for required roles in the appropriate section:
realm_access.rolesfor realm rolesresource_access.[client-id].rolesfor client roles
Example: Verifying User Roles in Node.js
To enforce secure access control, backend services must check the roles embedded in each userβs JWT token.
The example below shows how to validate both realm and client-level roles:
function hasRole(token, roleName, clientId = null) {
// Check realm roles
if (!clientId && token.realm_access && token.realm_access.roles) {
return token.realm_access.roles.includes(roleName);
}
// Check client roles
if (clientId && token.resource_access && token.resource_access[clientId]) {
return token.resource_access[clientId].roles.includes(roleName);
}
return false;
}
// Usage
if (hasRole(decodedToken, 'payment-initiator', 'payment-service')) {
// Allow payment initiation
} else {
// Return 403 Forbidden
}
RBAC Best Practicesβ
To ensure secure access control, always validate user roles on the backend and properly enforce Role-Based Access Control (RBAC) as defined in Keycloak.
Follow the Principle of Least Privilege
- Assign users the minimum roles needed for their tasks.
- Regularly review and audit role assignments.
Implement Role Hierarchy
- Structure roles in a hierarchical manner.
- Higher-level roles can inherit permissions from lower-level roles.
Separate Duties
- Distribute sensitive operations across different roles.
- Require multiple roles for critical operations.
Regular Auditing
- Monitor role assignments and changes.
- Review access patterns and adjust roles as needed.
Document Role Definitions
- Maintain clear documentation of what each role can access.
- Ensure role names are descriptive and consistent.
Troubleshooting Authorization Issuesβ
| Issue | Possible Cause | Solution |
|---|---|---|
| Access Denied (403) | Missing required role | Check token for required roles and request appropriate access |
| Unexpected Access | Overly permissive role | Review and restrict role permissions |
| Missing Role in Token | Role not assigned or not included in token | Verify role assignment and token mapper configuration |
| Token Validation Failure | Expired or invalid token | Refresh the token or re-authenticate |