4.0 KiB
c77_rbac Usage Guide This guide helps beginner developers use the c77_rbac PostgreSQL extension to secure database tables with role-based access control (RBAC). All tables and functions are in the public schema with c77_rbac_ prefixes (e.g., c77_rbac_subjects, c77_rbac_apply_policy) to avoid conflicts with Laravel or other packages. Your application tables should use custom schemas (e.g., myapp.orders). What is c77_rbac? c77_rbac uses row-level security (RLS) to control table access. For example, a Chicago manager sees only Chicago orders, while an admin sees all orders. Admin rights use a global/all scope, so any user ID (e.g., '2', '999') can be an admin. Prerequisites
PostgreSQL 14 or later. A superuser (e.g., homestead) for installation. A database (e.g., c77_rbac_test). Basic SQL knowledge.
Step 1: Install the Extension
Log in as the superuser: psql -h 192.168.49.115 -p 5432 -U homestead -d c77_rbac_test
Create the extension: CREATE EXTENSION c77_rbac SCHEMA public;
This sets up c77_rbac_ tables and functions in public.
Exit: \q
Step 2: Set Up Your Application Schema Use a custom schema (e.g., myapp) for your tables.
Log in as your application user (e.g., app_user): psql -h 192.168.49.115 -p 5432 -U app_user -d c77_rbac_test
Create the myapp schema: CREATE SCHEMA myapp;
Create a test table: CREATE TABLE myapp.orders ( id SERIAL PRIMARY KEY, campus TEXT NOT NULL, amount NUMERIC );
Insert test data: INSERT INTO myapp.orders (campus, amount) VALUES ('chicago', 500), ('miami', 1500);
Step 3: Apply Row-Level Security (RLS)
Apply an RLS policy: SELECT public.c77_rbac_apply_policy('myapp.orders', 'view_sales_page', 'campus', 'campus');
myapp.orders: Table to secure. view_sales_page: Required permission. campus: Scope type. campus: Column for scope (e.g., chicago).
A NOTICE: policy "c77_rbac_policy" ... does not exist is normal for new tables.
Check the policy: \dp myapp.orders
Expect c77_rbac_policy with: c77_rbac_can_access('view_sales_page'::text, current_setting('c77_rbac.external_id'::text, true), 'campus'::text, campus)
Step 4: Assign Roles to Users Users have an external_id (e.g., '1', '2'). Admin rights use global/all.
Assign a sales manager role (Chicago): SELECT public.c77_rbac_assign_subject('1', 'sales_manager', 'campus', 'chicago'); SELECT public.c77_rbac_grant_feature('sales_manager', 'view_sales_page');
Assign an admin role (all data): SELECT public.c77_rbac_assign_subject('999', 'admin', 'global', 'all'); SELECT public.c77_rbac_grant_feature('admin', 'view_sales_page');
For another admin (e.g., '2'): SELECT public.c77_rbac_assign_subject('2', 'admin', 'global', 'all'); SELECT public.c77_rbac_grant_feature('admin', 'view_sales_page');
Step 5: Test Access
Chicago manager: SET "c77_rbac.external_id" TO '1'; SELECT * FROM myapp.orders;
Expected: id | campus | amount ----+---------+-------- 1 | chicago | 500
Admin (e.g., '2'): SET "c77_rbac.external_id" TO '2'; SELECT * FROM myapp.orders;
Expected: id | campus | amount ----+---------+-------- 1 | chicago | 500 2 | miami | 1500
Unauthorized user: SET "c77_rbac.external_id" TO 'unknown'; SELECT * FROM myapp.orders;
Expected: id | campus | amount ----+--------+--------
Step 6: Use in Your Application For Laravel:
Set user ID: DB::statement("SET c77_rbac.external_id TO '1'");
Query: SELECT * FROM myapp.orders;
Troubleshooting
No rows: Check role (c77_rbac_assign_subject) and feature (c77_rbac_grant_feature). Policy missing: Verify \dp myapp.orders. Re-run c77_rbac_apply_policy. NOTICE messages: Normal for new tables. Display quirk: \dp may show campus instead of myapp.orders.campus. This is cosmetic.
Notes
Use schema.table (e.g., myapp.orders) with c77_rbac_apply_policy. public is for c77_rbac_, Laravel, and third-party packages. Use myapp for app tables. c77_rbac_ tables are accessible to all database users. Manage roles responsibly. This covers c77_rbac only, not c77_rbac_laravel.
For help, ask your database administrator or the c77_rbac community.