Skip to content

[Feature]: Implement Row-Level Security (RLS) for Tenant Isolation - #101

Merged
ankittroy-21 merged 4 commits into
ankittroy-21:ESSoC'26from
ErebAsh:feat/rls-tenant-isolation
Jul 28, 2026
Merged

[Feature]: Implement Row-Level Security (RLS) for Tenant Isolation#101
ankittroy-21 merged 4 commits into
ankittroy-21:ESSoC'26from
ErebAsh:feat/rls-tenant-isolation

Conversation

@ErebAsh

@ErebAsh ErebAsh commented Jul 22, 2026

Copy link
Copy Markdown

Description:

What this PR does / why we need it:
GitPhone utilizes a central Supabase instance where users are currently isolated purely by application-level filtering (WHERE telegram_id = ?). This PR hardens the security model by enforcing PostgreSQL's native Row-Level Security (RLS) policies.

By applying RLS, we ensure that a backend bug or injection vulnerability cannot result in cross-tenant data exposure (e.g., exposing another user's GitHub tokens or staged file diffs).

Changes included in this PR:

  • Database Schema: Added RLS configuration and policies to users, staged_files, and commit_log tables in public/setup/schema.sql.
  • Migration Script: Included a safe, idempotent migration_rls.sql script to apply the changes to the production DB.
  • Backend Refactoring: Refactored supabase_service.py to dynamically construct user-scoped Supabase clients for user-facing flows. It now generates and passes a custom JWT (signed with SUPABASE_JWT_SECRET) in the Authorization header, enforcing RLS at the API gateway layer.
  • Dependencies: Added PyJWT to requirements.txt and updated .env.example.
  • Testing: Added an automated test script (backend/tests/test_rls.py) to explicitly verify that unauthorized cross-tenant data access is blocked by the database engine (returning 0 rows).

How to test these changes:

  1. Apply the public/setup/migration_rls.sql script in your Supabase SQL Editor.
  2. Go to the Supabase dashboard -> Project Settings -> API, copy your JWT Secret, and add it to backend/.env as SUPABASE_JWT_SECRET="<secret>".
  3. Run the automated test suite locally:
    cd backend
    pip install -r requirements.txt
    python tests/test_rls.py
    
    

Summary by CodeRabbit

  • Security

    • Added user-level data isolation for account, staged file, and commit history data.
    • Authenticated operations now enforce access based on the signed-in user.
    • Added database policies to prevent cross-user data access.
  • Configuration

    • Added example settings for authentication, integrations, environment, and webhook configuration.
  • Tests

    • Added coverage verifying that users cannot access another user’s staged files.

@ErebAsh
ErebAsh requested a review from ankittroy-21 as a code owner July 22, 2026 07:28
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e0874ba6-4f9b-4ffc-9ca0-7aef9c1ecacb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Adds Supabase RLS policies, per-user JWT-authenticated clients, user-scoped data-access routing, environment configuration, and an executable cross-user isolation test.

Changes

Row-level security enforcement

Layer / File(s) Summary
Database RLS policies
public/setup/schema.sql, public/setup/migration_rls.sql
Enables RLS on users, staged_files, and commit_log, with policies matching telegram_id to the JWT subject claim.
Authenticated Supabase data access
backend/supabase_service.py, backend/requirements.txt
Adds optional HS256 JWT client creation and routes user-scoped queries through get_client(telegram_id), while retaining the global client for administrative operations.
RLS configuration and isolation validation
backend/.env.example, backend/tests/test_rls.py
Documents Supabase and JWT settings and adds a test confirming User B cannot read User A’s staged file.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BackendOperation
  participant get_client
  participant Supabase
  participant RLS
  BackendOperation->>get_client: Pass telegram_id
  get_client->>Supabase: Send JWT-authenticated request
  Supabase->>RLS: Evaluate User isolation policy
  RLS-->>BackendOperation: Return rows matching JWT subject
Loading

Possibly related PRs

Suggested labels: enhancement, backend, ECSoC26, ECSoC26-L1

Suggested reviewers: ankittroy-21, ankittroy-21

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses the RLS, JWT-authenticated client, migration, and test requirements for #62.
Out of Scope Changes check ✅ Passed The changes stay focused on RLS enablement, auth context, migration, tests, and related config updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: implementing RLS for tenant isolation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/supabase_service.py`:
- Around line 23-37: Update get_client so a missing SUPABASE_JWT_SECRET raises
an error instead of falling back to the service-role client. Remove the
warning/fallback path while preserving the JWT-authenticated create_client flow
when the secret is available.

In `@backend/tests/test_rls.py`:
- Around line 6-11: Update the import setup in test_rls.py so the intentional
sys.path mutation no longer triggers Ruff E402/I001: either dynamically load
supabase_service after the path setup, or apply the narrowly scoped lint
exception for that import while preserving get_client usage and environment
loading order.
- Around line 19-22: Update the RLS test setup and assertions so missing
SUPABASE_JWT_SECRET explicitly skips or fails the test instead of returning
success, and replace unauthorized-result logging with an assertion that
result.data is empty. Preserve resource cleanup by keeping the existing cleanup
logic in a finally block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 95a318d3-2295-4772-b4ea-c9e33f8dd23e

📥 Commits

Reviewing files that changed from the base of the PR and between a58cdb4 and 5068f96.

📒 Files selected for processing (6)
  • backend/.env.example
  • backend/requirements.txt
  • backend/supabase_service.py
  • backend/tests/test_rls.py
  • public/setup/migration_rls.sql
  • public/setup/schema.sql

Comment thread backend/supabase_service.py
Comment thread backend/tests/test_rls.py Outdated
Comment thread backend/tests/test_rls.py
@ankittroy-21
ankittroy-21 changed the base branch from main to ESSoC'26 July 23, 2026 10:18
@ankittroy-21

Copy link
Copy Markdown
Owner

@ErebAsh merge conflict here

@ankittroy-21
ankittroy-21 merged commit a3b0ca1 into ankittroy-21:ESSoC'26 Jul 28, 2026
1 check passed
@ErebAsh
ErebAsh deleted the feat/rls-tenant-isolation branch July 28, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security]: Implement and enforce Supabase Row-Level Security (RLS) policies for multi-tenant data

2 participants