c77_rbac/USAGE-P1.md
2025-05-23 23:29:45 -05:00

9.0 KiB

c77_rbac Usage Guide - Part 1: Core Concepts and Basic Usage

This is Part 1 of the comprehensive c77_rbac usage guide. This part covers the fundamental concepts and basic usage patterns.

Complete Guide Structure:

  • Part 1: Core Concepts and Basic Usage (this document)
  • Part 2: Advanced Usage Scenarios and Time-Based Permissions
  • Part 3: Framework Integration (Laravel, Django, Rails)
  • Part 4: Real-World Examples and Performance Optimization
  • Part 5: Security Best Practices and Troubleshooting

Table of Contents

  1. Understanding c77_rbac Concepts
  2. Basic Usage Patterns

Understanding c77_rbac Concepts

What is Database-Level Authorization?

Traditional application authorization happens in your code:

// Traditional approach - authorization in application
if ($user->role === 'admin' || $user->department === $post->department) {
    return Post::all();  // Returns ALL posts, then filters in PHP
}

With c77_rbac, authorization happens at the database level:

// c77_rbac approach - authorization in database
return Post::all();  // Database automatically returns only allowed posts

Core Architecture

Application User (external_id: '123')
    ↓
Subject (database record linking external_id to internal ID)
    ↓
Subject_Roles (user has roles with specific scopes)
    ↓
Role_Features (roles have specific permissions/features)
    ↓
RLS Policies (database automatically filters data)

Key Components Explained

1. Subjects (Users)

-- Subjects link your application users to RBAC
INSERT INTO c77_rbac_subjects (external_id) VALUES ('user_123');

-- External ID should match your application's user identifier
-- Usually: Laravel User ID, Django user.id, Rails user.id, etc.

2. Roles

-- Roles are named collections of permissions
-- Examples: 'admin', 'manager', 'employee', 'customer', 'guest'

-- Roles get meaning through the features they're granted
SELECT public.c77_rbac_grant_feature('manager', 'approve_requests');
SELECT public.c77_rbac_grant_feature('manager', 'view_team_reports');

3. Features (Permissions)

-- Features are specific permissions that can be checked
-- Good naming convention: action_object
-- Examples:
SELECT public.c77_rbac_grant_feature('editor', 'view_posts');
SELECT public.c77_rbac_grant_feature('editor', 'create_posts');
SELECT public.c77_rbac_grant_feature('editor', 'edit_posts');
SELECT public.c77_rbac_grant_feature('moderator', 'delete_posts');
SELECT public.c77_rbac_grant_feature('admin', 'manage_users');

4. Scopes (Context)

-- Scopes define WHERE a role applies
-- Format: scope_type/scope_id

-- Examples:
'global/all'                    -- Global access to everything
'department/engineering'        -- Only engineering department
'region/north_america'         -- Only North America region  
'project/apollo_mission'       -- Only Apollo project
'customer/enterprise_client'   -- Only enterprise client data
'tenant/company_abc'           -- Multi-tenant: only company ABC

5. Row-Level Security Policies

-- Policies automatically filter database queries
-- Applied to tables to enforce permissions

-- Example: Users can only see posts in their department
SELECT public.c77_rbac_apply_policy(
    'posts',              -- table name
    'view_posts',         -- required feature
    'department',         -- scope type  
    'department_id'       -- column containing department ID
);

Basic Usage Patterns

Pattern 1: Simple Role-Based Access

Perfect for basic applications with clear role hierarchies.

-- Step 1: Define roles and their capabilities
SELECT public.c77_rbac_grant_feature('admin', 'manage_users');
SELECT public.c77_rbac_grant_feature('admin', 'view_all_data');
SELECT public.c77_rbac_grant_feature('admin', 'edit_all_data');

SELECT public.c77_rbac_grant_feature('manager', 'view_reports');
SELECT public.c77_rbac_grant_feature('manager', 'approve_requests');

SELECT public.c77_rbac_grant_feature('employee', 'view_own_data');
SELECT public.c77_rbac_grant_feature('employee', 'submit_requests');

-- Step 2: Assign users to roles
SELECT public.c77_rbac_assign_subject('1', 'admin', 'global', 'all');
SELECT public.c77_rbac_assign_subject('101', 'manager', 'global', 'all');
SELECT public.c77_rbac_assign_subject('201', 'employee', 'global', 'all');

-- Step 3: Apply policies to tables
SELECT public.c77_rbac_apply_policy(
    'user_profiles', 'view_own_data', 'user', 'user_id'
);

-- Step 4: Use in your application
-- Set user context
SET "c77_rbac.external_id" TO '201';

-- Query automatically filtered
SELECT * FROM user_profiles;  -- Only returns data for user 201

Pattern 2: Department-Based Access

Common in organizations with department isolation.

-- Step 1: Create department-specific roles
SELECT public.c77_rbac_grant_feature('dept_admin', 'manage_dept_users');
SELECT public.c77_rbac_grant_feature('dept_admin', 'view_dept_data');
SELECT public.c77_rbac_grant_feature('dept_admin', 'edit_dept_data');

SELECT public.c77_rbac_grant_feature('dept_member', 'view_dept_data');
SELECT public.c77_rbac_grant_feature('dept_member', 'create_requests');

-- Step 2: Assign users to departments
SELECT public.c77_rbac_assign_subject('101', 'dept_admin', 'department', 'engineering');
SELECT public.c77_rbac_assign_subject('102', 'dept_member', 'department', 'engineering');
SELECT public.c77_rbac_assign_subject('201', 'dept_admin', 'department', 'marketing');

-- Step 3: Apply department-based policies
SELECT public.c77_rbac_apply_policy(
    'projects', 'view_dept_data', 'department', 'owning_department'
);

SELECT public.c77_rbac_apply_policy(
    'expenses', 'view_dept_data', 'department', 'department_code'
);

-- Step 4: Test department isolation
SET "c77_rbac.external_id" TO '102';  -- Engineering member
SELECT * FROM projects;  -- Only engineering projects
SELECT * FROM expenses;  -- Only engineering expenses

Pattern 3: Multi-Tenant Applications

Perfect for SaaS applications serving multiple clients.

-- Step 1: Define tenant-scoped roles
SELECT public.c77_rbac_grant_feature('tenant_admin', 'manage_tenant_users');
SELECT public.c77_rbac_grant_feature('tenant_admin', 'view_tenant_data');
SELECT public.c77_rbac_grant_feature('tenant_admin', 'configure_tenant');

SELECT public.c77_rbac_grant_feature('tenant_user', 'view_tenant_data');
SELECT public.c77_rbac_grant_feature('tenant_user', 'edit_own_data');

-- Step 2: Assign users to tenants
SELECT public.c77_rbac_assign_subject('1001', 'tenant_admin', 'tenant', 'company_a');
SELECT public.c77_rbac_assign_subject('1002', 'tenant_user', 'tenant', 'company_a');
SELECT public.c77_rbac_assign_subject('2001', 'tenant_admin', 'tenant', 'company_b');

-- Step 3: Apply tenant isolation policies
SELECT public.c77_rbac_apply_policy(
    'accounts', 'view_tenant_data', 'tenant', 'tenant_id'
);

SELECT public.c77_rbac_apply_policy(
    'invoices', 'view_tenant_data', 'tenant', 'tenant_id'
);

SELECT public.c77_rbac_apply_policy(
    'users', 'view_tenant_data', 'tenant', 'tenant_id'
);

-- Step 4: Perfect tenant isolation
SET "c77_rbac.external_id" TO '1002';  -- Company A user
SELECT * FROM accounts;  -- Only Company A accounts
SELECT * FROM invoices;  -- Only Company A invoices

Pattern 4: Hierarchical Organizations

For complex organizational structures with multiple levels.

-- Step 1: Define hierarchical roles
-- Global level
SELECT public.c77_rbac_grant_feature('global_admin', 'manage_everything');
SELECT public.c77_rbac_grant_feature('global_admin', 'view_all_regions');

-- Regional level  
SELECT public.c77_rbac_grant_feature('regional_manager', 'manage_region');
SELECT public.c77_rbac_grant_feature('regional_manager', 'view_region_data');

-- Branch level
SELECT public.c77_rbac_grant_feature('branch_manager', 'manage_branch');
SELECT public.c77_rbac_grant_feature('branch_manager', 'view_branch_data');

-- Store level
SELECT public.c77_rbac_grant_feature('store_manager', 'manage_store');
SELECT public.c77_rbac_grant_feature('store_manager', 'view_store_data');

-- Step 2: Assign users to hierarchy levels
SELECT public.c77_rbac_assign_subject('1', 'global_admin', 'global', 'all');
SELECT public.c77_rbac_assign_subject('101', 'regional_manager', 'region', 'west_coast');
SELECT public.c77_rbac_assign_subject('201', 'branch_manager', 'branch', 'west_coast_sf');
SELECT public.c77_rbac_assign_subject('301', 'store_manager', 'store', 'sf_downtown');

-- Step 3: Apply hierarchical policies
SELECT public.c77_rbac_apply_policy(
    'sales_data', 'view_store_data', 'store', 'store_code'
);

SELECT public.c77_rbac_apply_policy(
    'inventory', 'view_branch_data', 'branch', 'branch_code'
);

-- Step 4: Each level sees appropriate data
SET "c77_rbac.external_id" TO '301';  -- Store manager
SELECT * FROM sales_data;  -- Only their store's data

Continue to Part 2: Advanced Usage Scenarios for time-based permissions, conditional permissions, dynamic role assignment, and bulk operations.