Closed riderx closed 1 year ago
Current solution used:
let loop = true
let now = new Date().toISOString()
while (loop) {
const { data, error } = await supabase
.from('test_realtime_rls')
.select()
.single()
if (data && !error) {
console.log('payload', data)
}
now = new Date().toISOString()
await wait(1000)
}
It kind of self DDOS, but this is only used during onboarding of my users, so that will be like that until something better appear
This is a followup to https://github.com/supabase/realtime/issues/470#issuecomment-1475446726.
@riderx Yes, something like https://github.com/supabase/realtime/issues/470#issuecomment-1476237539.
https://github.com/supabase/realtime/issues/470#issuecomment-1476250161
did you sign your own token and pass that in?
@w3b6x9 that will require to my side to refactor the whole system who work already for normal query with header, the latest solution is not optimal but works. Do allowing the header to pass is planned in the near future? otherwise , I will try to plan a change to forge JWT, but for the CLI context it looks huge work compared to the actual super simple solution.
Do allowing the header to pass is planned in the near future?
@riderx we do not plan to support this in the near term.
I think your looping query above is a nice workaround.
Let me know if you decide to sign your own JWT or continue with the looping query you shared above.
Ok thanks !
@w3b6x9 do you still not have any plans to support this? Would you be open to a PR for that?
A warning in the supabase documentation to never use the request headers in RLS would be useful to avoid people designing the wrong solution only to find out later that it will never work with realtime.
@NoRKin we're changing some things around regarding how we use RLS for authorization and this feature is planned to be added (this is a draft PR, the real implementation is yet to be implemented but it will be similar)
@filipecabaco does this PR add support to RLS working with request headers in realtime?
Also running into this issue.
Is there a way to detect in postgres when a function is being called within the realtime context? Could at least add a temporary workaround for RLS rules. But I tried e.g. current_setting('realtime.channel_name', TRUE)
and it returns NULL
.
It's impossible to have a multi-account setup without headers. Only option seems to be issuing a new JWT per account, but that doesn't work well across tabs either.
@lauri865 You might need to turn on the feature by adding the channel to have RLS...
From the temp docs at github discussions... https://github.com/orgs/supabase/discussions/22484
But just a guess.
Just to reiterate, this is our setup: We have a multi-account setup whereby a JWT is issued for an array of accounts. Which account is active depends on the URL slug or subdomain. This can be achieved with PostgREST without an issue with headers (either reading referrer or setting a custom header with selected account_id).
Now, the problem is with realtime, where it's not possible to set request headers. Which makes computing the RLS impossible, as we don't know which account is selected from the JWT.
And before anyone suggests that we forge a new token, it's a strict requirement to be able to use different accounts across tabs. That would make the token refreshing logic quite complex, and another thing we would have to handle on our own without supabase.
I think it would be great if realtime.subscription
table also stored either supabase.realtime.params
or supabase.realtime.headers
values (which would be loaded into request.headers
or request.params
), which could then be used to compute RLS policies against. That would close the gap between REST + realtime.
On a side-note, the only way I could find to check if postgres function is called within the realtime context is the following – quite contrived, but essentially adding a custom claim to the subscription table, which then becomes accessible through request.jwt.claims.realtime
. It's not a solution to the above, but enabled us to add a temporary workaround that doesn't make realtime completely unusable (we can only use it for the primary account for the time being):
CREATE OR REPLACE FUNCTION app.set_realtime_token()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $function$
BEGIN
NEW.claims := jsonb_set(NEW.claims, '{realtime}', to_jsonb(true), true);
RETURN NEW;
END
$function$;
CREATE OR REPLACE TRIGGER set_realtime_token
BEFORE INSERT OR UPDATE ON realtime.subscription
FOR EACH ROW
EXECUTE FUNCTION app.set_realtime_token();
Bug report
Describe the bug
Custom header in Supabse SDK are not present to use in RLS as it is for query.
To Reproduce
Create a table
test_rls
with real-time and RLSAdd this RLS on ALL
Then set the SDK like that:
Now register a real-time listener:
And do insert with default value
Expected behavior
Insert should work, and a log payload should appear.
Where, in fact, only the insert works.
If I disable RLS and do insert again, the payload is logged.
System information
Additional context
I did try many solutions unsuccessfully: https://github.com/supabase/realtime/issues/470 https://github.com/supabase/supabase-js/issues/553#issuecomment-1432161145 https://discord.com/channels/839993398554656828/1087461400647049377/1087461400647049377
This is coming from a use case of my product Capgo. Where I created apikey ( access key) system for my users to use in the CLI of Capgo who is used in their CI/CD. Using the login/password, seems not reliable to me in that case. I know that made me an edge case of the SDK.
Hope I found an easy way to explain how to reproduce it.