mmmrrr

mmmrrr

Postgres row level security as a means to authorization

So I was thinking about the options we have on authorization (read: methods to find out what a user is allowed to do in our application). Of course I know about the plug / elixir based solutions like policy_wonk and canary, but I have the feeling that this is simply not the correct approach, given we have a database like postgres as the default choice for a datastore.

While researching about this topic I found PostgREST [1], a haskell library for auto generated REST apis based on a postgres dataschema. Long story short, with this package I miss a lot I take for granted with elixir and phoenix and it makes the deployment a lot more complicated. But I must say that I love how they solved the data access story.

The idea, as I understand it, is that every DB request is performed using different database roles with varying permission levels. That way you minimize impact if a rouge query manages to get through your defense. The next step is to check, on the database level, if the requesting user can see the specified row (i. e. there is the id of the owner embedded into the row). For an example please see [2]

The only similar thing I have seen in elixir land is mbuhot/ecto_row_level_security, which looks promising.

Question

So now on to the real questions:

  • Do you think it is a good approach, to let the database handle the authorization for your application?
  • Would you still rather use a dataloader library like canary?

Sources
[1] : http://postgrest.org/en/v5.2/tutorials/tut1.html
[2] : https://github.com/subzerocloud/postgrest-starter-kit/blob/master/db/src/authorization/privileges.sql#L22

Marked As Solved

mmmrrr

mmmrrr

Actually, there is: you are bound to Postgres (or at least systems which implement such a concept), which makes it an ill fit for a lot of problems.

The main problem I saw back then (which was why I tried to gather some opinions here :wink:), was that you start coupling business logic with the datastore. This makes it - imho - completely inadequate for the usage with Ecto, which is an abstraction layer for database queries.

IMO there are two options one could implement in Elixir:

  1. Make a nice library which wraps all those details in a consumer friendly Elixir API and goes all in with Postgres and nothing else
  2. Do it like Hasura.io and implement an “SQL-compiler” which you can feed some DSL to express the rules that apply to a specific cell and then emits a query that fulfills all those rules

I started a sloppy implementation of the second back then but it is relatively complicated to get right - and it simply had no priority, so it went nowhere.

The first solution might be the easier of those two options but is hardly something that could be adopted in phoenix by default because the framework needs to also support SQLite, MariaDB and MSSQL out of the box.

Also Liked

tadasajon

tadasajon

I’m surprised this thread did not receive any comments. Row-level security seems like an elegant way to increase security while simplifying the elixir/phoenix code. Shouldn’t this be the default way all phoenix apps are built? Is there any good reason not to use it?

al2o3cr

al2o3cr

The simplest reason, IMO, is that there’s a finite amount of CPU available to the database. Spending that budget on stuff besides answering database queries is fine, until you need it for queries.

Historically, scaling databases (especially for writes) is significantly harder than scaling the less-stateful tiers in front of them.

mmmrrr

mmmrrr

Supabase is a clever combination of different “best in class” technologies: PostgreSQL as the datastore, PostgREST as the API layer, Phoenix for database change subscriptions, a storage layer / middleware in TypeScript utilizing AWS S3, GoTrue for authentication and Kong as a proxy.

While I like this approach of using “the right tool for the job” it is definitively harder to operate than a majestic monolith in Phoenix…

dimitarvp

dimitarvp

Not sure but didn’t Supabase offer this? Recently they started publishing some of their code as open source so that could help, maybe.

tadasajon

tadasajon

I agree that this shouldn’t be the approach that Phoenix uses by default. I would compare using Postgres this way to using Tailwind – Phoenix shouldn’t default everyone into using Tailwind, but it seems to be the approach to CSS that many people in the the community agree is the best. You mention being “bound to Postgres” like it is a drawback, but many people see “access to Postgres” as a feature – we are talking about one of the most fully-featured and reliable database systems on offer – certainly more than adequate for over 90% or maybe over 99% of the scenarios that anyone would be using Phoenix for. In any case, there is a fair amount of commitment to a database that I guess I have come to expect – so, given that we’re making a commitment to Postgres anyway, why not make full use of it’s power and just go with row-level security? Building the app closer to the metal is always a good idea, other things being equal, it seems.

Where Next?

Popular in Questions Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement