-
-
Notifications
You must be signed in to change notification settings - Fork 721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: [Pg] support for row level security #1481
Conversation
|
||
export type PgPolicyFor = 'select' | 'insert' | 'update' | 'delete' | 'all'; | ||
|
||
export type PgPolicyTo = 'public' | 'current_role' | 'current_user' | 'session_user'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Supabase, we have other roles like authenticated
, etc.
Maybe the type could be 'public' | 'current_role' | 'current_user' | 'session_user' | (string & {})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you handle that with AnyPgRole
, sorry.
But, how can we use existing roles not created by us in the schema?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.existing()
like for views?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could inline the pgRole in the config like this:
{ to: [pgRole("my_existing_role")] }
Because all it needs is the name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good
What about |
We should ask the community, but I think RLS should be enable by default or at least print a warning during migration. |
Those should work the same way it works for tables. Drizzle-kit should diff your schema against what's on the DB and generate alter/drop/create accordingly |
I think drizzle should do the same as postgres, you have to enable it. Aren't all tables protected by the connection password? |
Not when using Supabase (DB is exposed through a web api). You have a big warning. But you are right, Drizzle have to follow postgres. |
Right 😅 |
…cy and PgRole extends from those now
…and added `rlsConfig` option to `PgTransactionConfig`
…t support transactions
@@ -29,6 +30,14 @@ export interface PgTransactionConfig { | |||
isolationLevel?: 'read uncommitted' | 'read committed' | 'repeatable read' | 'serializable'; | |||
accessMode?: 'read only' | 'read write'; | |||
deferrable?: boolean; | |||
rlsConfig?: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about (suggestion):
set?: {
configs?: {
name: string;
value: string;
isLocal?: boolean;
}[];
role?: AnyPgRole;
};
set
because postgres commands start withset
orset_
configs
because ofset_config(...)
And I think it is not only related to rls.
We can imagine wanting to use this to set_config, which is later used in a PG function that we called in our transaction.
Like https://www.postgresql.org/docs/current/sql-syntax-calling-funcs.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, set_config(...)
is not just for policies. I like set: { configs: ..., role: ... }
or set_configs: ..., set_role: ...
.
I use RLS policies without Supabase, and this looks good to me! It's key that Something to consider is that naming policies can be tediously repetitive if you tend to stick to one policy per table per operation. I've found the convention |
This would be a bad idea, just like how NextJS 13 started enabling caching by default. If Postgres didn't enable RLS by default, there's a reason to that. But at least to us, we don't buy into RLS is the answer to auth check everything in Postgres itself for 4 reasons:
In addition, if your database provider isn't providing a private network and secure connection with long random password (or even better, something like IAM access policy) + SSL, you should definitely push them to do so. All the production workloads I had worked on that touches sensitive data including money movement are all putting their database inside VPC with restricted port at the very least. |
Ideally warning on tables without policies would be a configurable option. If RLS is being used in a project, one probably wants policies on all tables.
You probably are pushing access control logic into your queries and thus into your DB anyways ( All RLS does is automatically add the same query clauses to every query (for a role) that you would've otherwise had to manually add in your application code every time you wrote a restricted query. |
If this warning is only showing up because of you choose to opt-in to use RLS in
Yes, definitely. As I mentioned, RLS might work on some products where the product users don't get to define the roles/permissions although I'm not sure how one can easily unit test the different roles on different code paths when the roles set grow tremendously. Also, note that not every engineer has direct access to production database due to compliance/regulatory needs which would make the maintenance/debugging with RLS policies tedious. In our current case, we do have some roles/permissions that are defined by the users themselves. If we're to use RLS for this, this would mean we need to implement additional validation/review logic to ensure the RLS policies that users manage won't be causing security issues which itself can become an additional layer of complexity that defeats the purpose of using RLS in the first place. |
@cayter Good point, there are some restrictions that are implemented as query clauses but are still best built on the application side. |
Just to don't forget that: We should reset role at the end of the transaction. await tx.execute(sql`RESET ROLE;`) |
Any progress on this? |
I really wish this feature will get merged soon |
Can anyone tell when it's merging or any updates |
👋 The team has been notified that there is some interest in this feature. |
Starting the review and discussion of an API. After that, we will fix anything that needs to be changed before releasing it |
Any updates on this one? Super important for me |
Any news? @AndriiSherman 🙏 |
Will this be included in the next release? |
I'm checking the commits/changelogs in the beta branch once per week to see if the RLS support has been added. |
If I understand correctly, it's close to beta |
Can you please share it, please? |
This was implemented by the team. |
This PR will close #594.
The changes in this PR will not do anything on their own, as this is mostly a migration/push feature from drizzle-kit.
Upon merging this, the user will be able to define roles and policies in the schema like this:
This is a WIP PR. Still looking into how to run
enable row level security
on the tables.Maybe we can do this?