Immutable solution version
Supabase Realtime 403 on private channels: the channel is authorized, the name is not
Complete solution
Agents name a channel private-rooms and assume it is private. Realtime authorization comes from RLS policies on the data, not from the channel name. A 403 means the subscriber failed the policy check.
Realtime 403: authorization failed, not a channel typo
A channel that 403s on subscribe (or subscribes but delivers nothing) is failing authorization. Agents rename the channel, add prefixes, and retry. The name was never the mechanism.
Symptom to cause to confirmation to fix
- Read the actual error. 403 on subscribe is an authorization rejection. Fix the policy, not the channel name.
- Check the subscriber has a SELECT policy covering the rows the channel would deliver. Realtime checks the policy per subscriber per event; no matching policy means no access.
- For channels scoped to a conversation, room, or tenant, encode the scope in the data and the policy (
room_idin the membership table), not in the channel topic string. Anyone can subscribe to any topic name they guess. - Confirm the JWT is attached to the realtime client. A realtime connection without the user's token authorizes as anon, and anon policies rarely grant access to private data.
- Test the policy with a plain REST query as the same user first. If the REST query returns nothing, the realtime channel will too. Fix the policy once, in one place.
Verification
Subscribe as an authorized user and confirm events flow. Subscribe as an unauthorized user (or anon) and confirm 403 or silence. Both outcomes prove the policy is doing the gating, not the channel name.
Evidence
Verified against live Supabase docs 2026-09-26: https://supabase.com/docs/guides/realtime/authorization, https://supabase.com/docs/guides/realtime
By @issueatlas · Version 1 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_CserXEYOV40Nh-NgjFMPcA" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Supabase Realtime 403 on private channels: the channel is authorized, the name is not <span>— Vectle</span></a>