MIKE-03: Authorization, tenancy and Row Level Security

✅ merged · #5 · Edu-Carone-SA/mike ← Edu-Carone-SA/mike · opened 1mo ago by EduardoCarone · merged 1mo ago by EduardoCarone · self · +2,958-19 across 15 files · ↗ on GitHub

From the PR description

MIKE-03: Authorization, tenancy and Row Level Security

Baseline

  • Base SHA: 8c977d4 (Sprint 2 merge)
  • Backend lint: 0 errors / 0 warnings
  • Frontend lint: 0 errors / 0 warnings
  • Tests before: 144 (59 backend + 85 frontend)
  • Critical/high vulnerabilities: 0

Changes

RLS Migration (20260710_01_rls_all_tables.sql)

  • Enabled RLS on 15 previously-unprotected tables
  • Created 82 RLS policies (SELECT/INSERT/UPDATE/DELETE)
  • Policies cover user-scoped access, shared resources, and child tables via EXISTS subqueries
  • Reference data tables (courtlistener) get read-only policies
  • contact_messages remains locked to service_role (no policies = admin-only)
  • Rollback migration included
  • schema.sql updated for fresh installs
  • Verification script: backend/scripts/verify-rls.sql

Tenancy Model (docs/security/tenancy-model.md)

  • Documented user-scoped model with optional sharing
  • 5-layer access control architecture documented
  • Service-role key policy documented
  • Sharing model for projects, workflows, and tabular reviews
  • Known limitations and roadmap documented

Route Security Classification (docs/security/route-security-classification.md)

  • All 90 routes classified: PUBLIC (2), AUTHENTICATED (87), AUTHENTICATED_MFA (8)
  • Access check documented for every route
  • New route checklist defined
  • Sprint 0 P0 correction: /case-law/case-opinions was ALWAYS authenticated (caseLawRouter.use(requireAuth))

E2E Updates

  • Removed KNOWN_SECURITY_BLOCKER from case-law test
  • Replaced with proper auth tests (anonymous → 401, invalid token → 401)
  • smoke-local.sh updated to use POST and expect 401

New Tests (82 tests in 4 files)

  • rls-policies.test.ts (19 tests) - Verifies migration covers all tables and operations
  • authorization-cross-user.test.ts (23 tests) - Tests access.ts helpers (owner/shared/denied)
  • route-security-classification.test.ts (20 tests) - Verifies all routes use requireAuth
  • case-law-auth.test.ts (20 tests) - Tests case-law endpoint authentication

Evidences

  • Backend tests: 141 passed (16 files)
  • Frontend tests: 85 passed (7 files)
  • Total: 226 tests, all green
  • Backend lint: 0/0, Frontend lint: 0/0
  • Typecheck: green
  • Builds: green

Residual Risks

  1. AGPL-3.0 compliance - Legal review still pending (P0, non-technical)
  2. No audit trail - Access events not logged (roadmap: Sprint 12)
  3. No role system - All users equal (roadmap: Sprint 9)
  4. No session revocation - JWTs valid until expiry (roadmap: Sprint 9)
  5. user_id type inconsistency - uuid vs text across tables
  6. 8 moderate vulnerabilities - Require breaking changes (deferred)

Rollback

  • Revert this PR
  • Apply 20260710_01_rls_all_tables_rollback.sql to drop policies
  • RLS can remain enabled (harmless without policies - just blocks all non-service-role access)

Our analysis

Enforce tenancy with row-level security — read the full analysis →

Think the analysis missed something the PR description covers?

Capture this PR into my fork

Download a Markdown prompt that tells Claude how to port every commit in this PR into your working tree. Run it via claude -p < capture-pull-5.md from inside the repo you want the changes in.

⬇ Download capture-pull-5.md