Prev Next

Database / Supabase Intermediate to Advanced Interview Questions

Why do private Realtime channels need their own RLS-style authorization check?

A Realtime Broadcast or Presence channel isn't backed by a specific table row the way a Postgres Changes event is — there's no underlying SELECT ... WHERE for Postgres's RLS engine to filter, because the "message" being sent might be an arbitrary payload like a cursor position or a chat line that never touches a table at all.

Without a dedicated authorization step, any client holding a valid JWT could subscribe to any channel name and both read and publish messages on it, since a channel name alone (like room-42) carries no inherent permission information the server can check against ordinary table policies. Requiring an explicit authorization check — typically a function that looks up whether the calling user is actually a participant in that room — closes that gap, making channel access something the application deliberately grants per user rather than something implied just by knowing (or guessing) a channel's name.

Why can't ordinary table RLS protect a Broadcast/Presence channel the way it protects Postgres Changes?
Without private-channel authorization, what could an attacker do just by knowing a channel name?

More Related questions...

How does Supabase expose custom Postgres functions as callable RPC endpoints? What is the difference between a SECURITY DEFINER and a SECURITY INVOKER Postgres function? How does pg_cron enable scheduled jobs directly inside a Supabase Postgres database? What is the difference between a read replica and the primary database in a Supabase project? When should you use a read replica versus scaling the primary database's resources? What is the difference between daily backups and Point-in-Time Recovery in Supabase? How does Supabase's database branching feature isolate schema changes per git branch? When would you choose a preview branch over testing migrations directly in staging? What is the difference between a custom access token hook and a raw JWT claim? Why should you avoid embedding sensitive business data directly inside JWT claims? How does Supabase support anonymous sign-ins, and how do you convert one to a permanent account? What is the difference between linking an OAuth identity and creating a brand-new user account? How is Storage object access controlled compared to table-level Row Level Security? What is the difference between resumable (TUS) uploads and standard uploads in Supabase Storage? How does Supabase's image transformation feature resize images without a separate CDN service? What is the difference between LISTEN/NOTIFY and Supabase Realtime's Postgres Changes channel? What is the difference between schema-per-tenant and RLS-based multi-tenancy? Why is EXPLAIN ANALYZE useful before optimizing a slow Supabase query? What is the difference between JSONB and a fully normalized relational schema in Postgres? When should you use a JSONB column instead of creating additional relational tables? How does wrapping auth.uid() in a subquery improve Row Level Security performance? Why do we use SECURITY DEFINER functions when RLS would otherwise block a needed operation? How does pg_net let Postgres make asynchronous HTTP calls without blocking a transaction? Explain the lifecycle of a Point-in-Time Recovery (PITR) backup in Supabase? How does a custom access token Auth Hook let you enrich a user's JWT with custom claims? How does Supabase enforce multi-factor authentication (MFA) at the session level? Why doesn't disabling RLS on a table make it invisible in the auto-generated API docs? Explain the internal working of Supabase Vault for storing encrypted secrets in Postgres? Why should you store third-party API keys in Vault instead of a plain table column? When should you choose LISTEN/NOTIFY over Supabase Realtime for internal service communication? How can you optimize a multi-tenant schema design using Row Level Security instead of schema-per-tenant? How do you troubleshoot a Postgres query that performs well in the SQL editor but slowly through the REST API? Explain the execution flow of a private Realtime broadcast channel authorized by Row Level Security? Why do private Realtime channels need their own RLS-style authorization check? How does Supabase's connection string differ between the direct connection, session pooler, and transaction pooler? Why doesn't the transaction pooler support prepared statements the way a direct connection does? How can you optimize zero-downtime schema migrations for a table already receiving production traffic? What happens when a long-running migration locks a table that's still receiving live writes? How does Supabase Studio's SQL editor differ from running migrations through the CLI in a CI pipeline? Which is better for production schema changes, editing directly in Studio or CLI-managed migrations, and why?
Show more question and Answers...


Comments & Discussions