Skip to content

fix(0003,0006,0015): lint user-authored RLS policies in storage and realtime - #202

Open
djedi-knight wants to merge 1 commit into
supabase:mainfrom
djedi-knight:fix/35-rls-lints-storage-realtime
Open

djedi-knight wants to merge 1 commit into
supabase:mainfrom
djedi-knight:fix/35-rls-lints-storage-realtime

Conversation

@djedi-knight

Copy link
Copy Markdown

fix(0003,0006,0015): lint user-authored RLS policies in storage and realtime

Closes #35.

Problem

Users write their own RLS policies on storage.objects and realtime.messages. The lints that inspect policy content excluded both schemas entirely, so slow or insecure policies there went unreported. For example, owner = auth.uid() on storage.objects is a very common policy, and it re-evaluates the function for every row.

Change

This follows the precedent of #88, which re-enabled 0003 on realtime. It removes storage and realtime from the exclusion list of the lints that judge policy content:

Lint storage realtime
0003 auth_rls_initplan added already enabled (#88)
0006 multiple_permissive_policies added not added, see below
0015 rls_references_user_metadata added added

Left unchanged on purpose:

0006 on realtime: 0006 only inspects relkind = 'r', and realtime.messages is a partitioned table (relkind = 'p'). Removing realtime from its exclusion list would pass a test but never fire in production. Covering partitioned tables in 0006 is a separate change that also affects public, so it isn't in this PR.

Tests

  • New cases in the 0003, 0006 and 0015 tests. They create a policy on storage.objects (and on realtime.messages for 0015) and expect one finding. They also create the same policy on an auth table and expect none.
  • The new tests fail against the current lints and pass with this change.
  • The full suite passes (29/29) on supabase/postgres:15.14.1.169. The final splinter.sql validity step also passes.
  • Existing expected output is unchanged; the change only adds lines.
  • splinter.sql was regenerated with bin/compile.py. All pre-commit hooks pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_017TAbfjJfpipDmD7NJuQmPx

…ealtime

Users write their own RLS policies on storage.objects and
realtime.messages, but the policy-content lints excluded those schemas
entirely, so slow or insecure policies there went unreported (supabase#35).

Following the precedent of supabase#88 (0003 on realtime), drop the schemas
from the exclusion lists of the lints that inspect policy content:

- 0003 auth_rls_initplan: add storage (realtime already enabled)
- 0006 multiple_permissive_policies: add storage
- 0015 rls_references_user_metadata: add storage and realtime

Lints about table configuration (0007, 0008, 0013) stay excluded,
since users can't change RLS settings on Supabase-owned tables, and
auth stays excluded everywhere. 0006 is not re-enabled on realtime: it
only inspects relkind 'r', and realtime.messages is partitioned.

Tests cover the new storage/realtime findings and that auth remains
excluded. splinter.sql regenerated with bin/compile.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017TAbfjJfpipDmD7NJuQmPx
@djedi-knight
djedi-knight requested a review from a team as a code owner October 15, 2026 18:59

This branch has not been deployed

No deployments
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.

Re-enable some RLS Lints on storage/auth/realtime tables

1 participant