graphql-engine icon indicating copy to clipboard operation
graphql-engine copied to clipboard

provide JWT token in transactions

Open ElixirMike opened this issue 5 years ago • 15 comments
trafficstars

In my Postgres DB, I have some tables where I have specified some default inserts based on passed in JWT token claims. This was from using a different solution..but utlimately, in Postgres, I could specify the variable using this format for example. I could place this in the default value, such that upon insert, it would use the logged in users "userid" value.

(current_setting('request.jwt.claims.userid'::text, true))::integer

Does Hasura pass the JWT claims to Postgres like this? I tried the above, but nothing was recognized so I'm wondering if you don't pass them or if you use a different format.

ElixirMike avatar Feb 12 '20 16:02 ElixirMike

https://docs.hasura.io/1.0/graphql/manual/schema/default-values/index.html

arjunyel avatar Feb 12 '20 17:02 arjunyel

Yes, I'm familiar with those settings, but when it mentions role based column presets, it's all done through Hasura permissions.

https://docs.hasura.io/1.0/graphql/manual/schema/default-values/column-presets.html

I was explicitly asking if Hasura passes these Sessions to Postgres so that I can reference them directly in postgres tables, Like how I showed in my previous posting.

ElixirMike avatar Feb 12 '20 17:02 ElixirMike

@ElixirMike if you want to see the query sent to Postgres for a given graphql query, enable the logging for queries, and observe the logs (using docker-compose logs, or whatever, depending on how you're running it).

You'll be able to see the SQL query (as a function, with arguments passed in). It's fairly big, so it may be a bit difficult to understand what's going on.

pnappa avatar Feb 13 '20 04:02 pnappa

Thanks, but not exactly what I was looking for. I've used a tool called Postgrest, which allows PostGres SQL to access JWT claoms through GUC variables that are set by Postres per request.

Here is the snippet that explains: http://postgrest.org/en/v6.0/auth.html#web-users-sharing-role

I'm guessing Hasura has a different implementation, but this feature would be very nice to add.. The ability to include whatever we want in the JWT claim, and then have direct access to this data in Postgres direclty enables a bunch of different scenarios. The most important one for me is to be able to use RLS (Row Level Security) directly in Postgres.

ElixirMike avatar Feb 13 '20 13:02 ElixirMike

@ElixirMike,

Maybe this is what you are looking for: https://docs.hasura.io/1.0/graphql/manual/guides/auditing-tables.html

leoalves avatar Feb 13 '20 18:02 leoalves

@ElixirMike can you explain your use-case in a bit more detail, of accessing session variables in Postgres? That will help us to get a better understanding. A concrete example will be immensely helpful.

Currently, you can access the session variables only inside Postgres functions. See https://docs.hasura.io/1.0/graphql/manual/schema/custom-functions.html#accessing-hasura-session-variables-in-custom-functions . Let us know if this helps.

ecthiender avatar Feb 14 '20 11:02 ecthiender

Sure, I've posted a separate thread on this, but will restate here. The way Hasura permissions works is problematic for my use-case, which allows users to dynamically define their tables. When adding a field to a table, the only current solution for permissions is to totally delete/remove permissions from the table, and then re-apply all permissions again. This is a very heavy transaction and very slow. And it happens on every field add/delete to a table.

I'm looking for work-around solution and was hoping that I could use Postgres Row level security for my permissions....but this requires I have access to the sessions variable so I can define the appropriate RLS policies. This is how permissions work with a similar solution to Hasura called PostGREST . But it does not look like that's supported here..

ultimately I'm just trying to find a performant solution for implementing permissions in my solution.

ElixirMike avatar Feb 14 '20 13:02 ElixirMike

@ElixirMike Got it. Thanks for the reply!

I can see the other thread you mention here: https://github.com/hasura/graphql-engine/issues/2104#issuecomment-585758423

As you have guessed, currently, there is no support. But we will look into this and get back to you.

ecthiender avatar Feb 17 '20 13:02 ecthiender

@ElixirMike I am not sure if I understand your use case completely, but I can point to some notes that could help.

For mutations, which are executed in a transaction, current_setting('hasura.user') will give you the session variables. For example, if you want to access the user id, you can do current_setting('hasura.user')->>'x-hasura-user-id' (see more at https://docs.hasura.io/1.0/graphql/manual/guides/auditing-tables.html#auditing-actions-on-tables-in-postgres)

For queries, using custom functions, they can be used as described in this page: https://docs.hasura.io/1.0/graphql/manual/schema/custom-functions.html#accessing-hasura-session-variables-in-custom-functions

Let me know if any of this helps.

shahidhk avatar Feb 18 '20 08:02 shahidhk

@ElixirMike just checking in if your problem is solved? 🙂

marionschleifer avatar Feb 24 '20 06:02 marionschleifer

@shahidhk I'd really like that current_setting thing to work with SELECTs as well. In my use case, postgres is accessed through multiple paths, and Hasura is only one of them. For my REST API, I'm passing authentication through to postgres via local session variables. With Hasura, I'd essentially like to forward the JWT received to postgres. Looks like that happens with mutations but not queries. (My REST approach was actually inspired by this Hasura pattern, but I didn't realize it only did it with mutations.)

m4dc4p avatar Feb 27 '20 18:02 m4dc4p

@marionschleifer @shahidhk I was able to use custom functions and track_function v2 to pass session information from Hasura to Postgres outside a mutation (awesome!!!). I do lose the ability to construct arbitrary GraphQL queries over my tracked tables (not awesome).

Is there any way I can help make this a priority feature? Would you accept a PR for it?

m4dc4p avatar Feb 29 '20 01:02 m4dc4p

Another use-case

extract the "sub" value from our JWTs and use that to enforce tenant separation

tirumaraiselvan avatar Mar 11 '20 10:03 tirumaraiselvan

I was also looking into this for my permissions system.

For exemple, I have a case where a user may have many roles (x-hasura-allowed-roles), each of which may give access to different ressources of a reservation system. I would like to expose a custom function that takes the JWT claims as a parameter to return ressource specific access. This way I can easily retrieve and present to a user the informations / operations to which they have access with their given roles.

ghost avatar Mar 13 '20 21:03 ghost

Passing session variables to SELECT queries would be very useful... Is this made on purpose, so that Hasura users would be incentivized to use Hasura's RBAC feature instead of working with native postgresql RLS?

Gintasz avatar Oct 07 '24 20:10 Gintasz