# c77_rbac Tutorial - Part 3: Implementing RBAC **Tutorial Navigation:** - [Part 1: Getting Started](TUTORIAL-Part1.md) - Prerequisites and installation - [Part 2: Building the TechCorp Database](TUTORIAL-Part2.md) - Creating the schema and data - **Part 3: Implementing RBAC** (this document) - Setting up roles and permissions - [Part 4: Row-Level Security](TUTORIAL-Part4.md) - Applying access controls - [Part 5: Testing and Validation](TUTORIAL-Part5.md) - Security testing - [Part 6: Advanced Features](TUTORIAL-Part6.md) - Bulk operations and monitoring --- ## Chapter 3: Setting Up RBAC Roles and Features Now we'll implement a comprehensive role-based access control system for our TechCorp database. This chapter covers defining features, creating roles, and assigning users to appropriate roles with proper scoping. ### Step 1: Define Company-Wide Features Features represent specific permissions that can be checked in your application. Let's define features that match our TechCorp organizational structure: ```sql -- System Administration Features SELECT public.c77_rbac_grant_feature('system_admin', 'manage_all_users'); SELECT public.c77_rbac_grant_feature('system_admin', 'access_all_departments'); SELECT public.c77_rbac_grant_feature('system_admin', 'view_all_salaries'); SELECT public.c77_rbac_grant_feature('system_admin', 'manage_system_settings'); SELECT public.c77_rbac_grant_feature('system_admin', 'view_audit_logs'); SELECT public.c77_rbac_grant_feature('system_admin', 'export_all_data'); -- Department Management Features SELECT public.c77_rbac_grant_feature('dept_manager', 'view_dept_employees'); SELECT public.c77_rbac_grant_feature('dept_manager', 'manage_dept_projects'); SELECT public.c77_rbac_grant_feature('dept_manager', 'approve_dept_expenses'); SELECT public.c77_rbac_grant_feature('dept_manager', 'view_dept_salaries'); SELECT public.c77_rbac_grant_feature('dept_manager', 'create_dept_documents'); SELECT public.c77_rbac_grant_feature('dept_manager', 'view_confidential_docs'); -- Regular Employee Features SELECT public.c77_rbac_grant_feature('employee', 'view_own_profile'); SELECT public.c77_rbac_grant_feature('employee', 'update_own_profile'); SELECT public.c77_rbac_grant_feature('employee', 'view_company_handbook'); SELECT public.c77_rbac_grant_feature('employee', 'submit_expenses'); SELECT public.c77_rbac_grant_feature('employee', 'view_own_expenses'); SELECT public.c77_rbac_grant_feature('employee', 'access_internal_docs'); -- Project Team Features SELECT public.c77_rbac_grant_feature('project_member', 'view_project_details'); SELECT public.c77_rbac_grant_feature('project_member', 'edit_project_documents'); SELECT public.c77_rbac_grant_feature('project_member', 'view_project_expenses'); SELECT public.c77_rbac_grant_feature('project_member', 'submit_project_expenses'); SELECT public.c77_rbac_grant_feature('project_lead', 'manage_project_team'); SELECT public.c77_rbac_grant_feature('project_lead', 'approve_project_expenses'); SELECT public.c77_rbac_grant_feature('project_lead', 'create_project_documents'); -- Contractor Features (limited access) SELECT public.c77_rbac_grant_feature('contractor', 'view_own_profile'); SELECT public.c77_rbac_grant_feature('contractor', 'view_assigned_projects'); SELECT public.c77_rbac_grant_feature('contractor', 'submit_expenses'); SELECT public.c77_rbac_grant_feature('contractor', 'access_project_docs'); -- HR Specific Features SELECT public.c77_rbac_grant_feature('hr_staff', 'view_all_employees'); SELECT public.c77_rbac_grant_feature('hr_staff', 'manage_employee_data'); SELECT public.c77_rbac_grant_feature('hr_staff', 'access_hr_documents'); SELECT public.c77_rbac_grant_feature('hr_staff', 'view_salary_data'); -- Finance Specific Features SELECT public.c77_rbac_grant_feature('finance_staff', 'view_all_expenses'); SELECT public.c77_rbac_grant_feature('finance_staff', 'approve_expenses'); SELECT public.c77_rbac_grant_feature('finance_staff', 'view_budget_data'); SELECT public.c77_rbac_grant_feature('finance_staff', 'access_financial_docs'); -- Sales Specific Features SELECT public.c77_rbac_grant_feature('sales_staff', 'view_sales_data'); SELECT public.c77_rbac_grant_feature('sales_staff', 'manage_customer_info'); SELECT public.c77_rbac_grant_feature('sales_staff', 'access_sales_docs'); ``` ### Step 2: Sync Admin Features The `admin` role should have access to all features. Let's sync all existing features to the admin role: ```sql -- Make sure system admin gets all features SELECT public.c77_rbac_sync_admin_features(); -- Check what features were granted to admin SELECT * FROM public.c77_rbac_get_role_features('admin'); -- Also sync features to our system_admin role SELECT public.c77_rbac_sync_admin_features(); ``` ### Step 3: Assign Roles to Users Now we'll assign our TechCorp users to appropriate roles with proper scoping: ```sql -- System Administrator (Alice) SELECT public.c77_rbac_assign_subject('1', 'system_admin', 'global', 'all'); -- Department Managers SELECT public.c77_rbac_assign_subject('101', 'dept_manager', 'department', 'ENG'); -- Bob SELECT public.c77_rbac_assign_subject('201', 'dept_manager', 'department', 'SALES'); -- Frank SELECT public.c77_rbac_assign_subject('301', 'dept_manager', 'department', 'HR'); -- Iris SELECT public.c77_rbac_assign_subject('401', 'dept_manager', 'department', 'FIN'); -- Kelly SELECT public.c77_rbac_assign_subject('501', 'dept_manager', 'department', 'MKT'); -- Maya -- HR Staff (need special access across departments) SELECT public.c77_rbac_assign_subject('301', 'hr_staff', 'global', 'all'); -- Iris (manager) SELECT public.c77_rbac_assign_subject('302', 'hr_staff', 'global', 'all'); -- Jack -- Finance Staff (need expense access across departments) SELECT public.c77_rbac_assign_subject('401', 'finance_staff', 'global', 'all'); -- Kelly (manager) SELECT public.c77_rbac_assign_subject('402', 'finance_staff', 'global', 'all'); -- Liam -- Regular Employees (department-scoped) SELECT public.c77_rbac_assign_subject('102', 'employee', 'department', 'ENG'); SELECT public.c77_rbac_assign_subject('103', 'employee', 'department', 'ENG'); SELECT public.c77_rbac_assign_subject('202', 'employee', 'department', 'SALES'); SELECT public.c77_rbac_assign_subject('203', 'employee', 'department', 'SALES'); SELECT public.c77_rbac_assign_subject('502', 'employee', 'department', 'MKT'); -- Contractors (department-scoped with limited access) SELECT public.c77_rbac_assign_subject('104', 'contractor', 'department', 'ENG'); -- Project-specific roles SELECT public.c77_rbac_assign_subject('101', 'project_lead', 'project', '1'); -- Bob leads Portal project SELECT public.c77_rbac_assign_subject('103', 'project_lead', 'project', '2'); -- Dave leads Mobile project SELECT public.c77_rbac_assign_subject('102', 'project_member', 'project', '1'); -- Carol on Portal SELECT public.c77_rbac_assign_subject('102', 'project_member', 'project', '2'); -- Carol on Mobile SELECT public.c77_rbac_assign_subject('104', 'project_member', 'project', '1'); -- Eve on Portal -- Bulk assign basic employee role to all the additional users we created SELECT * FROM public.c77_rbac_bulk_assign_subjects( (SELECT array_agg(id::text) FROM users WHERE id BETWEEN 1001 AND 1050), 'employee', 'department', 'ENG' -- Assign them all to engineering for this example ); ``` ### Step 4: Verify Role Assignments Let's check that our role assignments are working correctly: ```sql -- Check Alice's (admin) permissions SELECT 'Alice (System Admin) - Roles:' as info; SELECT * FROM public.c77_rbac_get_user_roles('1'); -- Check Bob's (engineering manager) permissions SELECT 'Bob (Engineering Manager) - Roles:' as info; SELECT * FROM public.c77_rbac_get_user_roles('101'); -- Check Carol's (developer) permissions SELECT 'Carol (Developer) - Roles:' as info; SELECT * FROM public.c77_rbac_get_user_roles('102'); -- Check Iris's (HR manager) permissions SELECT 'Iris (HR Manager) - Roles:' as info; SELECT * FROM public.c77_rbac_get_user_roles('301'); -- Check system summary SELECT 'System Summary:' as info; SELECT * FROM public.c77_rbac_summary; ``` ### Step 5: Understanding RBAC Scoping Let's explore how different scoping patterns work in our system: ```sql -- Global scope (system-wide access) -- Example: Alice has system_admin role with global/all scope SELECT 'Global Admin Access Example:' as demo; SELECT public.c77_rbac_can_access('manage_all_users', '1', 'global', 'all') as alice_can_manage_all; -- Department scope (department-specific access) -- Example: Bob can manage engineering department but not sales SELECT 'Department Scope Examples:' as demo; SELECT public.c77_rbac_can_access('manage_dept_projects', '101', 'department', 'ENG') as bob_can_manage_eng; SELECT public.c77_rbac_can_access('manage_dept_projects', '101', 'department', 'SALES') as bob_cannot_manage_sales; -- Project scope (project-specific access) -- Example: Carol is a member of projects 1 and 2 SELECT 'Project Scope Examples:' as demo; SELECT public.c77_rbac_can_access('view_project_details', '102', 'project', '1') as carol_can_view_proj1; SELECT public.c77_rbac_can_access('view_project_details', '102', 'project', '3') as carol_cannot_view_proj3; -- Cross-department access for special roles -- Example: Iris (HR) can access all departments SELECT 'Cross-Department Access Example:' as demo; SELECT public.c77_rbac_can_access('view_all_employees', '301', 'global', 'all') as iris_can_see_all; ``` ### Step 6: Create Role Hierarchy Visualization Let's create a query to visualize our role hierarchy: ```sql -- Create a comprehensive view of our RBAC setup SELECT 'TechCorp RBAC Role Distribution:' as title; SELECT r.name as role_name, sr.scope_type, sr.scope_id, count(*) as user_count, string_agg(s.external_id, ', ' ORDER BY s.external_id::integer) as user_ids FROM public.c77_rbac_roles r JOIN public.c77_rbac_subject_roles sr ON r.role_id = sr.role_id JOIN public.c77_rbac_subjects s ON sr.subject_id = s.subject_id GROUP BY r.name, sr.scope_type, sr.scope_id ORDER BY r.name, sr.scope_type, sr.scope_id; -- Show feature distribution across roles SELECT 'Feature Distribution:' as title; SELECT r.name as role_name, count(f.name) as feature_count, string_agg(f.name, ', ' ORDER BY f.name) as features FROM public.c77_rbac_roles r JOIN public.c77_rbac_role_features rf ON r.role_id = rf.role_id JOIN public.c77_rbac_features f ON rf.feature_id = f.feature_id GROUP BY r.name ORDER BY count(f.name) DESC, r.name; ``` **✅ Checkpoint 3:** You now have a complete RBAC setup with realistic corporate roles! --- ## Understanding Our RBAC Structure ### Role Hierarchy 1. **System Admin** (`system_admin`) - Scope: `global/all` - Access: Everything across all departments and projects - Users: Alice (ID: 1) 2. **Department Managers** (`dept_manager`) - Scope: `department/[DEPT_CODE]` - Access: Full control within their department - Users: Bob (ENG), Frank (SALES), Iris (HR), Kelly (FIN), Maya (MKT) 3. **Specialized Staff** - **HR Staff** (`hr_staff`): Global access to employee data - **Finance Staff** (`finance_staff`): Global access to financial data - **Sales Staff** (`sales_staff`): Access to sales-specific features 4. **Regular Employees** (`employee`) - Scope: `department/[DEPT_CODE]` - Access: Basic departmental access and own data 5. **Project Roles** - **Project Leads** (`project_lead`): Scope: `project/[PROJECT_ID]` - **Project Members** (`project_member`): Scope: `project/[PROJECT_ID]` 6. **Contractors** (`contractor`) - Scope: `department/[DEPT_CODE]` or `project/[PROJECT_ID]` - Access: Limited, task-specific access ### Key Scopes Used - **`global/all`**: System-wide access (admins, HR, finance) - **`department/[CODE]`**: Department-specific access (ENG, SALES, HR, FIN, MKT) - **`project/[ID]`**: Project-specific access (1, 2, 3, 4, 5) ### Permission Patterns - **Inheritance**: Users can have multiple roles with different scopes - **Escalation**: `global/all` scope overrides specific scopes - **Isolation**: Department and project scopes provide isolation - **Flexibility**: Same user can have different roles in different contexts --- ## Advanced Role Management ### Adding New Roles Dynamically ```sql -- Example: Create a "Senior Developer" role with enhanced permissions SELECT public.c77_rbac_grant_feature('senior_developer', 'view_project_details'); SELECT public.c77_rbac_grant_feature('senior_developer', 'edit_project_documents'); SELECT public.c77_rbac_grant_feature('senior_developer', 'mentor_junior_developers'); SELECT public.c77_rbac_grant_feature('senior_developer', 'approve_code_reviews'); -- Assign Dave as a senior developer in the engineering department SELECT public.c77_rbac_assign_subject('103', 'senior_developer', 'department', 'ENG'); -- Verify the assignment SELECT * FROM public.c77_rbac_get_user_roles('103'); ``` ### Bulk Role Operations ```sql -- Example: Assign all engineering employees to a "code_reviewer" role -- First create the role SELECT public.c77_rbac_grant_feature('code_reviewer', 'review_code'); SELECT public.c77_rbac_grant_feature('code_reviewer', 'comment_on_pull_requests'); -- Bulk assign to engineering employees SELECT * FROM public.c77_rbac_bulk_assign_subjects( ARRAY['101', '102', '103', '104'], -- Engineering team 'code_reviewer', 'department', 'ENG' ); ``` ### Temporary Access Patterns ```sql -- Example: Grant temporary access for a cross-departmental project -- Marketing person needs temporary engineering access for a joint project SELECT public.c77_rbac_assign_subject('502', 'project_member', 'project', '1'); -- Later, you can revoke this access -- SELECT public.c77_rbac_revoke_subject_role('502', 'project_member', 'project', '1'); ``` --- ## What's Next? Now that we have a comprehensive RBAC system set up, in **Part 4** we'll implement Row-Level Security (RLS) policies that will automatically enforce these permissions at the database level: - Apply RLS policies to our TechCorp tables - Implement sophisticated business rules for document access - Create multi-level security controls - Test automatic data filtering based on user roles **Continue to [Part 4: Row-Level Security](TUTORIAL-Part4.md)** --- ## Chapter Summary In this chapter, you've successfully: ### ✅ Created a Comprehensive Permission System - **40+ features** covering all aspects of TechCorp operations - **10+ roles** with realistic corporate hierarchy - **65+ user assignments** with proper scoping ### ✅ Implemented Advanced Scoping Patterns - **Global access** for system admins and cross-departmental roles - **Department isolation** for managers and employees - **Project-based collaboration** for cross-functional teams - **Contractor limitations** for external workers ### ✅ Demonstrated RBAC Flexibility - **Multiple roles per user** (e.g., department manager + project lead) - **Hierarchical permissions** (global overrides departmental) - **Dynamic role assignment** for changing business needs - **Bulk operations** for efficient management ### ✅ Established Security Foundation - **Role-based feature access** with proper validation - **Scoped permissions** preventing unauthorized access - **Audit-ready structure** with timestamps and tracking - **Scalable design** that grows with organizational needs The RBAC system is now ready for Row-Level Security implementation, which will automatically enforce these permissions at the database query level.