c77_rbac/USAGE.md

4.7 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

  1. Log in as the superuser:

    psql -h 192.168.49.115 -p 5432 -U homestead -d c77_rbac_test
    
  2. Create the extension:

    CREATE EXTENSION c77_rbac SCHEMA public;
    

    This sets up c77_rbac_ tables and functions in public.

  3. Exit:

    \q
    

Step 2: Set Up Your Application Schema

Use a custom schema (e.g., myapp) for your tables.

  1. 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
    
  2. Create the myapp schema:

    CREATE SCHEMA myapp;
    
  3. Create a test table:

    CREATE TABLE myapp.orders (
        id SERIAL PRIMARY KEY,
        campus TEXT NOT NULL,
        amount NUMERIC
    );
    
  4. Insert test data:

    INSERT INTO myapp.orders (campus, amount) VALUES ('chicago', 500), ('miami', 1500);
    

Step 3: Apply Row-Level Security (RLS)

  1. 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.

  2. 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.

  1. 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');
    
  2. 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

  1. Chicago manager:

    SET "c77_rbac.external_id" TO '1';
    SELECT * FROM myapp.orders;
    

    Expected:

     id | campus  | amount 
    ----+---------+--------
     1 | chicago |    500
    
  2. 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
    
  3. 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:

  1. Set user ID:

    DB::statement("SET c77_rbac.external_id TO '1'");
    
  2. 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.