Overview
CompanyFlow implements Role-Based Access Control (RBAC) to manage what authenticated users can do within the system. Authorization determines which actions users can perform on specific resources based on their assigned role.Core Concepts
Roles
Roles define a set of permissions that can be assigned to employees. CompanyFlow includes both system roles and custom roles./home/daytona/workspace/source/database/migration/002_create_roles_and_permissions.sql:1-11
System roles have
company_id = NULL and are available globally. Custom roles are scoped to a specific company.System Roles
CompanyFlow includes four predefined system roles:/home/daytona/workspace/source/database/migration/002_create_roles_and_permissions.sql:15-19
Super Admin
Full AccessComplete control over all company resources, settings, and employee management.
HR Manager
HR AdministrationManage employees, departments, leaves, and other HR-related resources.
Manager
Team ManagementApprove leave requests, manage team members, and view subordinate information.
Employee
Self-ServiceAccess own profile, submit leave requests, and view personal information.
Permissions
Permissions define granular access controls for specific actions on resources:/home/daytona/workspace/source/database/migration/002_create_roles_and_permissions.sql:21-32
- Action - What operation can be performed (create, read, update, delete, approve, reject, manage)
- Resource - Which entity the permission applies to (employees, leaves, company_settings, etc.)
- Conditions - Optional constraints (e.g., only own department, only subordinates)
Authorization Flow
1. Authentication
First, the user must authenticate and receive a JWT token containing their role:2. Role Validation
API endpoints specify which roles are permitted to access them:/home/daytona/workspace/source/handlers/employee_handler.go:46-51
3. Authorization Check
TheauthorizeEmployeeToken function validates the user’s role:
/home/daytona/workspace/source/handlers/employee_handler.go:311-334
- Extract JWT token from Authorization header
- Validate token signature and expiry
- Extract user’s role from claims
- Check if role is in the allowed roles list
- Return error if unauthorized
Endpoint Authorization
Different endpoints require different role combinations:Employee Management
| Endpoint | Allowed Roles | Description |
|---|---|---|
POST /companies/{id}/employees | Super Admin, HR Manager | Create new employee |
GET /employees/{id} | Super Admin, HR Manager | View employee details |
PUT /employees/{id} | Super Admin, HR Manager | Update employee |
DELETE /employees/{id} | Super Admin, HR Manager | Delete employee |
GET /companies/{id}/employees | Super Admin, HR Manager | List all employees |
Leave Management
| Endpoint | Allowed Roles | Description |
|---|---|---|
POST /companies/{id}/leave-types | Super Admin, HR Manager | Create leave type |
POST /leaves | Employee, Manager | Submit leave request |
GET /leaves/{id} | Super Admin, HR Manager, Employee, Manager | View leave details |
POST /leaves/{id}/approve | Super Admin, HR Manager, Manager | Approve leave |
POST /leaves/{id}/reject | Super Admin, HR Manager, Manager | Reject leave |
Department Management
| Endpoint | Allowed Roles | Description |
|---|---|---|
POST /companies/{id}/departments | Super Admin, HR Manager | Create department |
GET /departments/{id} | Super Admin, HR Manager | View department |
PUT /departments/{id} | Super Admin, HR Manager | Update department |
DELETE /departments/{id} | Super Admin, HR Manager | Delete department |
Role Constants
Role names are defined as constants in handlers:/home/daytona/workspace/source/handlers/department_handler.go:16-19
Permission Conditions
Theconditions JSONB field in the permissions table allows for conditional access:
{"department": "own"}- Only access resources in own department{"level": "subordinate"}- Only manage direct reports{"status": "pending"}- Only interact with pending items
While the schema supports conditional permissions, the current implementation primarily uses role-based checks. Custom permission conditions can be implemented in service layer logic.
Custom Roles
Companies can create custom roles tailored to their organizational structure. Custom roles:- Are scoped to a specific
company_id - Can be assigned custom permissions
- Use the same permission model as system roles
- Are managed through the roles API endpoints
Multi-Tenant Authorization
Authorization is enforced per tenant using thecompany_id from the JWT token:
/home/daytona/workspace/source/handlers/employee_handler.go:293-308
Error Responses
Unauthorized access attempts return appropriate error responses:Best Practices
Principle of Least Privilege
Assign the minimum role necessary for users to perform their job functions.
Regular Audits
Periodically review role assignments to ensure they remain appropriate.
Use System Roles
Leverage built-in system roles before creating custom ones.
Document Custom Roles
Clearly document the purpose and permissions of any custom roles created.
Related Concepts
Authentication
Learn how users authenticate and receive role claims
Multi-Tenancy
Understand how authorization is scoped per company