Complete reference for role-based access control (RBAC) in CHRIS.
Role Hierarchy
admin
└── hr_manager
└── employee
Higher roles inherit all permissions from lower roles.
Roles Overview
admin
Full system access. Can configure all settings and manage all data.
Typical users: System administrators, IT staff
hr_manager
HR operations access. Can manage employees and approve leave.
Typical users: HR personnel, department heads
employee
Basic access. Can manage own profile and submit requests.
Typical users: All regular employees
Permission Matrix
Profiles (Employee Data)
| Action | admin | hr_manager | employee |
|---|---|---|---|
| View own profile | ✓ | ✓ | ✓ |
| Edit own profile | ✓ | ✓ | ✓ |
| View all profiles | ✓ | ✓ | - |
| Edit any profile | ✓ | ✓ | - |
| Create employee | ✓ | ✓ | - |
| Delete employee | ✓ | - | - |
| View HR notes | ✓ | ✓ | - |
| Edit HR notes | ✓ | ✓ | - |
| Masquerade as user | ✓ | - | - |
Leave Requests
| Action | admin | hr_manager | employee | team_leader |
|---|---|---|---|---|
| View own requests | ✓ | ✓ | ✓ | ✓ |
| Submit request | ✓ | ✓ | ✓ | ✓ |
| Cancel own pending | ✓ | ✓ | ✓ | ✓ |
| View all requests | ✓ | ✓ | - | - |
| View team requests | ✓ | ✓ | - | ✓ |
| Approve/reject any | ✓ | ✓ | - | - |
| Approve/reject team | ✓ | ✓ | - | ✓ |
| Revoke approved | ✓ | ✓ | - | - |
Teams
| Action | admin | hr_manager | employee |
|---|---|---|---|
| View all teams | ✓ | ✓ | ✓ |
| Create team | ✓ | ✓ | - |
| Edit team | ✓ | ✓ | - |
| Delete team | ✓ | - | - |
| Assign members | ✓ | ✓ | - |
Settings
| Action | admin | hr_manager | employee |
|---|---|---|---|
| View company settings | ✓ | - | - |
| Edit company settings | ✓ | - | - |
| Configure SMTP | ✓ | - | - |
| Manage leave types | ✓ | - | - |
| Manage holidays | ✓ | ✓ | - |
| View audit logs | ✓ | ✓ | - |
| Manage translations | ✓ | - | - |
Contracts
| Action | admin | hr_manager | employee |
|---|---|---|---|
| View own contract | ✓ | ✓ | ✓ |
| View any contract | ✓ | ✓ | - |
| Create contract | ✓ | ✓ | - |
| Edit contract | ✓ | ✓ | - |
| Delete contract | ✓ | - | - |
Team Leader Role
Team leaders are employees who lead one or more teams. This is not a separate role but additional permissions.
Identifying Team Leaders
// Check if user is a team leader
const { data: isLeader } = await supabase
.rpc('is_team_leader', { _user_id: userId });
Team Leader Permissions
In addition to employee permissions:
- View leave requests from team members
- Approve/reject team member requests
- View team calendar and availability
Assignment
Team leaders are assigned via the teams.lead_user_id field:
UPDATE teams
SET lead_user_id = 'user-uuid'
WHERE id = 'team-uuid';
Row Level Security (RLS)
Permissions are enforced at the database level via RLS policies.
Example Policies
Profiles - View own:
CREATE POLICY "Users can view own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);
Profiles - HR can view all:
CREATE POLICY "HR can view all profiles"
ON profiles FOR SELECT
USING (
EXISTS (
SELECT 1 FROM user_roles
WHERE user_id = auth.uid()
AND role IN ('admin', 'hr_manager')
)
);
Leave requests - Team leader view:
CREATE POLICY "Team leaders can view team requests"
ON leave_requests FOR SELECT
USING (
user_id IN (
SELECT id FROM profiles
WHERE team_id IN (
SELECT id FROM teams
WHERE lead_user_id = auth.uid()
)
)
);
Checking Permissions in Code
Using the Auth Hook
import { useAuth } from '@/hooks/useAuth';
function MyComponent() {
const { isAdmin, isHR, isEmployee, user } = useAuth();
if (isAdmin) {
// Show admin UI
} else if (isHR) {
// Show HR UI
} else {
// Show employee UI
}
}
Using RPC Functions
// Get user's role
const { data: role } = await supabase
.rpc('get_user_role', { _user_id: userId });
// Check specific role
const { data: isAdmin } = await supabase
.rpc('has_role', { _user_id: userId, _role: 'admin' });
Role Assignment
During Employee Creation
Roles are assigned when creating an employee:
await supabase.functions.invoke('create-employee', {
body: {
email: 'user@company.com',
full_name: 'John Doe',
role: 'hr_manager' // admin, hr_manager, or employee
}
});
Changing Roles
Only admins can change roles:
UPDATE user_roles
SET role = 'hr_manager'
WHERE user_id = 'user-uuid';
Best Practices
Principle of Least Privilege
Assign the minimum role needed:
- Most users should be
employee - Only HR staff need
hr_manager - Limit
adminto essential personnel
Role Auditing
Track role changes via audit logs:
SELECT * FROM audit_logs
WHERE entity_type = 'user_roles'
ORDER BY created_at DESC;
Testing Permissions
Use masquerade to test as different roles:
- Sign in as admin
- Masquerade as an employee
- Verify they see appropriate data
- Exit masquerade