Seed data sql files for testing Supabase throughout development
This commit is contained in:
parent
109f099a4c
commit
9048691ce1
|
|
@ -0,0 +1,22 @@
|
||||||
|
-- ============================================
|
||||||
|
-- Supabase Auth User Seeding (for dev/testing)
|
||||||
|
-- Required to satisfy FK constraint on users.id
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- ACME Users
|
||||||
|
INSERT INTO auth.users (id, email, encrypted_password)
|
||||||
|
VALUES
|
||||||
|
('00000000-0000-0000-0000-000000000001', 'jane@acme.com', 'hash-jane'),
|
||||||
|
('00000000-0000-0000-0000-000000000002', 'mark@acme.com', 'hash-mark');
|
||||||
|
|
||||||
|
-- Orion Users
|
||||||
|
INSERT INTO auth.users (id, email, encrypted_password)
|
||||||
|
VALUES
|
||||||
|
('00000000-0000-0000-0000-000000000003', 'kbrooks@orioncyber.io', 'hash-kyle'),
|
||||||
|
('00000000-0000-0000-0000-000000000004', 'tina@orioncyber.io', 'hash-tina');
|
||||||
|
|
||||||
|
-- Internal Roles
|
||||||
|
INSERT INTO auth.users (id, email, encrypted_password)
|
||||||
|
VALUES
|
||||||
|
('00000000-0000-0000-0000-000000000005', 'emily@complycore.com', 'hash-emily'),
|
||||||
|
('00000000-0000-0000-0000-000000000006', 'admin@complycore.com', 'hash-admin');
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
-- ==============================================
|
||||||
|
-- ComplyCore: Clean Dev Seed with Valid UUIDs
|
||||||
|
-- ==============================================
|
||||||
|
|
||||||
|
-- Clean tables (safe for dev only)
|
||||||
|
DELETE FROM auth_audit_log;
|
||||||
|
DELETE FROM evaluations;
|
||||||
|
DELETE FROM api_clients;
|
||||||
|
DELETE FROM users;
|
||||||
|
DELETE FROM tenants;
|
||||||
|
|
||||||
|
-- ---------------------
|
||||||
|
-- TENANTS
|
||||||
|
-- ---------------------
|
||||||
|
INSERT INTO tenants (id, name, cage_code, sam_uid, primary_contact_name, primary_contact_email)
|
||||||
|
VALUES
|
||||||
|
('11111111-1111-1111-1111-111111111111', 'ACME Defense Solutions', '5X9L2', 'JHE92SLMNTY4', 'Jane Smith', 'jane@acme.com'),
|
||||||
|
('22222222-2222-2222-2222-222222222222', 'Orion Cyber Systems', '9X4T1', 'AER74Q9MDK33', 'Kyle Brooks', 'kbrooks@orioncyber.io');
|
||||||
|
|
||||||
|
-- ---------------------
|
||||||
|
-- USERS
|
||||||
|
-- ---------------------
|
||||||
|
-- ACME users
|
||||||
|
INSERT INTO users (id, tenant_id, role, first_name, last_name, email, phone_office, job_title)
|
||||||
|
VALUES
|
||||||
|
('00000000-0000-0000-0000-000000000001', '11111111-1111-1111-1111-111111111111', 'client_admin', 'Jane', 'Smith', 'jane@acme.com', '555-1000', 'IT Manager'),
|
||||||
|
('00000000-0000-0000-0000-000000000002', '11111111-1111-1111-1111-111111111111', 'client_user', 'Mark', 'Lee', 'mark@acme.com', '555-2001', 'System Analyst');
|
||||||
|
|
||||||
|
-- Orion users
|
||||||
|
INSERT INTO users (id, tenant_id, role, first_name, last_name, email, phone_office, job_title)
|
||||||
|
VALUES
|
||||||
|
('00000000-0000-0000-0000-000000000003', '22222222-2222-2222-2222-222222222222', 'client_admin', 'Kyle', 'Brooks', 'kbrooks@orioncyber.io', '555-2002', 'Security Lead'),
|
||||||
|
('00000000-0000-0000-0000-000000000004', '22222222-2222-2222-2222-222222222222', 'client_user', 'Tina', 'Ramos', 'tina@orioncyber.io', '555-2003', 'Compliance Analyst');
|
||||||
|
|
||||||
|
-- Global users
|
||||||
|
INSERT INTO users (id, tenant_id, role, first_name, last_name, email, phone_office, job_title)
|
||||||
|
VALUES
|
||||||
|
('00000000-0000-0000-0000-000000000005', '11111111-1111-1111-1111-111111111111', 'reviewer', 'Emily', 'Nguyen', 'emily@complycore.com', '555-9001', 'CMMC Reviewer'),
|
||||||
|
('00000000-0000-0000-0000-000000000006', '11111111-1111-1111-1111-111111111111', 'superadmin', 'Michael', 'Kell', 'admin@complycore.com', '555-9999', 'Platform Owner');
|
||||||
|
|
||||||
|
-- ---------------------
|
||||||
|
-- SERVICE ACCOUNTS
|
||||||
|
-- ---------------------
|
||||||
|
INSERT INTO api_clients (
|
||||||
|
id, tenant_id, name, client_id, client_secret, scopes, description, created_by
|
||||||
|
) VALUES
|
||||||
|
('99999999-1111-1111-1111-111111111111', '11111111-1111-1111-1111-111111111111',
|
||||||
|
'ACME Upload Bot', 'acme-bot-1', 'acme-secret-1', ARRAY['upload', 'evaluate']::api_scope[],
|
||||||
|
'Auto uploader for ACME', '00000000-0000-0000-0000-000000000001'),
|
||||||
|
|
||||||
|
('99999999-2222-2222-2222-222222222222', '22222222-2222-2222-2222-222222222222',
|
||||||
|
'Orion CI/CD Service', 'orion-bot', 'orion-secret-token', ARRAY['upload', 'evaluate']::api_scope[],
|
||||||
|
'Orion automation client', '00000000-0000-0000-0000-000000000003');
|
||||||
|
|
||||||
|
-- ---------------------
|
||||||
|
-- EVALUATIONS
|
||||||
|
-- ---------------------
|
||||||
|
-- Predefined UUIDs for project consistency
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM evaluations WHERE id = '44444444-aaaa-aaaa-aaaa-aaaaaaaaaaaa') THEN
|
||||||
|
INSERT INTO evaluations (id, tenant_id, project_id, control_id, status, notes, created_by)
|
||||||
|
VALUES
|
||||||
|
-- ACME
|
||||||
|
('44444444-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '11111111-1111-1111-1111-111111111111',
|
||||||
|
'55555555-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'AC.1.001', 'implemented',
|
||||||
|
'Policy approved.', '00000000-0000-0000-0000-000000000002'),
|
||||||
|
|
||||||
|
('44444444-bbbb-bbbb-bbbb-bbbbbbbbbbbb', '11111111-1111-1111-1111-111111111111',
|
||||||
|
'55555555-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'AC.2.007', 'partial',
|
||||||
|
'Procedure referenced but not enforced.', '00000000-0000-0000-0000-000000000002'),
|
||||||
|
|
||||||
|
('44444444-cccc-cccc-cccc-cccccccccccc', '11111111-1111-1111-1111-111111111111',
|
||||||
|
'55555555-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'CM.2.063', 'missing',
|
||||||
|
'No documented process.', '00000000-0000-0000-0000-000000000002'),
|
||||||
|
|
||||||
|
-- Orion
|
||||||
|
('44444444-dddd-dddd-dddd-dddddddddddd', '22222222-2222-2222-2222-222222222222',
|
||||||
|
'55555555-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'IA.1.076', 'implemented',
|
||||||
|
'MFA enforced.', '00000000-0000-0000-0000-000000000004'),
|
||||||
|
|
||||||
|
('44444444-eeee-eeee-eeee-eeeeeeeeeeee', '22222222-2222-2222-2222-222222222222',
|
||||||
|
'55555555-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'AU.2.042', 'missing',
|
||||||
|
'No audit logs collected.', '00000000-0000-0000-0000-000000000004');
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- ---------------------
|
||||||
|
-- AUDIT LOG
|
||||||
|
-- ---------------------
|
||||||
|
INSERT INTO auth_audit_log (
|
||||||
|
id, actor_id, tenant_id, action, target_table, target_id, ip_address, user_agent, result
|
||||||
|
) VALUES
|
||||||
|
(gen_random_uuid(), '00000000-0000-0000-0000-000000000001', '11111111-1111-1111-1111-111111111111',
|
||||||
|
'login_success', NULL, NULL, '192.168.1.101', 'Chrome', 'success'),
|
||||||
|
|
||||||
|
(gen_random_uuid(), '99999999-1111-1111-1111-111111111111', '11111111-1111-1111-1111-111111111111',
|
||||||
|
'upload_evaluation', 'evaluations', '44444444-bbbb-bbbb-bbbb-bbbbbbbbbbbb', '10.0.1.15', 'bot/1.0', 'success'),
|
||||||
|
|
||||||
|
(gen_random_uuid(), '00000000-0000-0000-0000-000000000005', '22222222-2222-2222-2222-222222222222',
|
||||||
|
'view_evaluation', 'evaluations', '44444444-eeee-eeee-eeee-eeeeeeeeeeee', '192.168.5.25', 'Firefox', 'success');
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
# 🔐 ComplyCore Authentication & Authorization Design
|
||||||
|
|
||||||
|
**Component:** Identity & Access Management (IAM)
|
||||||
|
**Version:** v1.0
|
||||||
|
**Last Updated:** 2024-07-11
|
||||||
|
**Owner:** Kell Engineering
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Overview
|
||||||
|
|
||||||
|
ComplyCore uses a **multi-tenant, RBAC-enforced identity system** built on PostgreSQL with Supabase Auth. All user and system access is governed by:
|
||||||
|
|
||||||
|
- **Tenant isolation** via Row-Level Security (RLS)
|
||||||
|
- **Role-Based Access Control (RBAC)** via ENUM roles
|
||||||
|
- **Session-scoped variables** (`set_config()`) instead of legacy JWT hooks
|
||||||
|
- **Support for both human users and non-person entities (NPEs)**
|
||||||
|
- **Audit logging** for access, evaluation, and data modification events
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧱 Database Entity Model
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
erDiagram
|
||||||
|
tenants ||--o{ users : has
|
||||||
|
tenants ||--o{ api_clients : owns
|
||||||
|
tenants ||--o{ evaluations : owns
|
||||||
|
users ||--o{ evaluations : creates
|
||||||
|
users ||--o{ auth_audit_log : actor
|
||||||
|
api_clients ||--o{ auth_audit_log : actor
|
||||||
|
|
||||||
|
tenants {
|
||||||
|
UUID id PK
|
||||||
|
TEXT name
|
||||||
|
TEXT cage_code
|
||||||
|
TEXT sam_uid
|
||||||
|
}
|
||||||
|
|
||||||
|
users {
|
||||||
|
UUID id PK
|
||||||
|
UUID tenant_id FK
|
||||||
|
TEXT first_name
|
||||||
|
TEXT last_name
|
||||||
|
TEXT email
|
||||||
|
user_role role
|
||||||
|
}
|
||||||
|
|
||||||
|
api_clients {
|
||||||
|
UUID id PK
|
||||||
|
UUID tenant_id FK
|
||||||
|
TEXT client_id
|
||||||
|
TEXT client_secret
|
||||||
|
api_scope[] scopes
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluations {
|
||||||
|
UUID id PK
|
||||||
|
UUID tenant_id FK
|
||||||
|
TEXT control_id
|
||||||
|
TEXT status
|
||||||
|
}
|
||||||
|
|
||||||
|
auth_audit_log {
|
||||||
|
UUID id PK
|
||||||
|
UUID actor_id
|
||||||
|
UUID tenant_id FK
|
||||||
|
TEXT action
|
||||||
|
TEXT result
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 👤 User Roles
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
A[client_user] -->|RLS: Own tenant only| EvalTable
|
||||||
|
B[client_admin] -->|RLS: Own tenant only + mgmt| EvalTable
|
||||||
|
C[reviewer] -->|RLS: Read all tenants| EvalTable
|
||||||
|
D[superadmin] -->|RLS: Full control| EvalTable & UserTable
|
||||||
|
```
|
||||||
|
|
||||||
|
| Role | Description | Access Scope |
|
||||||
|
|--------------|----------------------------------|----------------------|
|
||||||
|
| `client_user`| End user | Own tenant only |
|
||||||
|
| `client_admin`| Tenant admin | Own tenant (plus user mgmt) |
|
||||||
|
| `reviewer` | Internal auditor or compliance | All tenants (read-only) |
|
||||||
|
| `superadmin` | Platform operator | Full access to all data |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 RLS Policies
|
||||||
|
|
||||||
|
| Table | Role(s) | Access Type | Rule Description |
|
||||||
|
|------------------|----------------------|-----------------|--------------------------------------------|
|
||||||
|
| `users` | All | Self only | `id = auth.uid()` |
|
||||||
|
| `evaluations` | `client_*` | Tenant-bound | Match tenant via `set_config()` |
|
||||||
|
| `evaluations` | `reviewer` | Global read | Unrestricted SELECT |
|
||||||
|
| `evaluations` | `superadmin` | Full access | Unrestricted ALL w/ check |
|
||||||
|
| `api_clients` | All | Own tenant only | `enabled=true` AND tenant match |
|
||||||
|
| `auth_audit_log` | All | Tenant-bound | Match tenant |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔑 Session Variables (No JWT Custom Claims)
|
||||||
|
|
||||||
|
Instead of deprecated JWT claim injection, ComplyCore uses:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT set_config('request.jwt.claim.role', user.role, true);
|
||||||
|
SELECT set_config('request.jwt.claim.tenant_id', user.tenant_id::text, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
This enables per-session RLS enforcement and simplifies system-wide access control.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ NPE: Non-Person Entities (API Clients)
|
||||||
|
|
||||||
|
**Table:** `api_clients`
|
||||||
|
|
||||||
|
| Field | Purpose |
|
||||||
|
|---------------|----------------------------------|
|
||||||
|
| `client_id` | Public API token ID |
|
||||||
|
| `client_secret` | Auth key (hashed) |
|
||||||
|
| `tenant_id` | Enforces scope per client |
|
||||||
|
| `scopes[]` | Least-privilege operations |
|
||||||
|
| `enabled` | Soft-delete / disable mechanism |
|
||||||
|
|
||||||
|
**Scopes Enum:**
|
||||||
|
- `upload`
|
||||||
|
- `evaluate`
|
||||||
|
- `read_reports`
|
||||||
|
- `manage_projects`
|
||||||
|
|
||||||
|
> RLS prevents disabled clients or cross-tenant access.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Audit Logging
|
||||||
|
|
||||||
|
**Table:** `auth_audit_log`
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|---------------|------------|----------------------------------------------|
|
||||||
|
| `actor_id` | UUID | User or service account |
|
||||||
|
| `tenant_id` | UUID | Organization context |
|
||||||
|
| `action` | TEXT | Description (e.g., `login_success`) |
|
||||||
|
| `target_table`| TEXT | Optional: table affected |
|
||||||
|
| `result` | TEXT | `success` or `fail` |
|
||||||
|
| `timestamp` | TIMESTAMP | System-generated UTC timestamp |
|
||||||
|
|
||||||
|
This log supports:
|
||||||
|
- Login tracking
|
||||||
|
- API usage validation
|
||||||
|
- Internal audit trail for CMMC/DFARS controls
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧠 CMMC Practice Coverage
|
||||||
|
|
||||||
|
| Practice | Control Area | Implementation |
|
||||||
|
|----------------------|-----------------------|----------------------------------------|
|
||||||
|
| AC.1.001 | Access Control | Unique accounts (auth.users + users) |
|
||||||
|
| AC.1.002 | Access Enforcement | RBAC and RLS |
|
||||||
|
| AC.1.003 | Least Privilege | Role + tenant-scoped access |
|
||||||
|
| AU.2.042 | Audit Logs | `auth_audit_log` |
|
||||||
|
| IA.2.078 | MFA Capable | `mfa_enabled` flag (enforced by UI) |
|
||||||
|
| SC.3.177 | NPE Separation | `api_clients` with isolated scopes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📎 Appendices
|
||||||
|
|
||||||
|
### 🔧 Initial Setup Function
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE OR REPLACE FUNCTION set_claim_context()
|
||||||
|
RETURNS void
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
v_role TEXT;
|
||||||
|
v_tenant UUID;
|
||||||
|
BEGIN
|
||||||
|
SELECT role, tenant_id INTO v_role, v_tenant
|
||||||
|
FROM public.users
|
||||||
|
WHERE id = auth.uid();
|
||||||
|
|
||||||
|
PERFORM set_config('request.jwt.claim.role', v_role, true);
|
||||||
|
PERFORM set_config('request.jwt.claim.tenant_id', v_tenant::text, true);
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
```
|
||||||
|
|
||||||
|
Call this at the start of every request/session to enforce scoped access.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Status
|
||||||
|
|
||||||
|
| Component | Status | Notes |
|
||||||
|
|--------------------|---------------|----------------------------------------|
|
||||||
|
| Supabase Auth | ✅ Integrated | Used for identity backing |
|
||||||
|
| Postgres Tables | ✅ Complete | tenants, users, api_clients, audits |
|
||||||
|
| RLS Policies | ✅ Enforced | All core tables |
|
||||||
|
| Session Claims | ✅ Supported | Via `set_config()` |
|
||||||
|
| MFA Support | 🟡 Flagged | Client-side UI pending |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Maintained by:** Kell Engineering
|
||||||
|
**Contact:** mtkell@kellengineering.com
|
||||||
|
**Document ID:** `AUTH-DOC-001`
|
||||||
|
|
||||||
Loading…
Reference in New Issue