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

Create permission check with a session variable in the LHS

Open marbemac opened this issue 4 years ago • 12 comments

Today one can use a session variable in a permission check on the right side of the equation (e.g. 'user_id' _eq 'X-Hasura-User-Id'). Being able to create a permission checks entirely from a session variables would be amazing (e.g. 'X-Hasura-User-Permissions' _includes 'project_write').

Our JWT token looks something like the below. On authentication, we lookup the user permissions, given their role, and assign them a token that includes a list of their permissions. When their role is changed, or the role<->permissions mapping in the db changes, tokens are refreshed (in addition to short expiration, etc).

{
  "iat": 1578806077,
  "exp": 1578806977,
  "iss": "xyz",
  "https://xyz.com/jwt/claims": {
    "x-hasura-default-role": "workspace_user",
    "x-hasura-permissions": ["projects_read", "projects_add", "workspace_write", "...etc"],
    "x-hasura-allowed-roles": ["anonymous", "user", "workspace_user"],
    "x-hasura-workspace-id": "48",
    "x-hasura-user-id": "3"
  } 
}

WIth Hasura's current permission system, we have to do something like this to check that the user has the appropriate permission. It involves actually looking up the permission from a table as part of the db query (rather than using the info that is already in the JWT token / session):

Screen Shot 2020-01-12 at 5 06 33 PM

Ideally, we'd be able to do something like this and create a permission check from just session values. This is much simpler, and keeps the generated DB queries clean since Hasura does not need to add extra logic to join/lookup permissions table - the info is already in the session itself.

Screen Shot 2020-01-12 at 5 23 51 PM

Curious if you all have already considered a feature like this?

marbemac avatar Jan 12 '20 23:01 marbemac

Since your permissions are very resource specific and tightly coupled to your domain, to your application logic, an alternative idea would be to simplify your DB design add the members columns directly into the workspaces table

... ... readers writers admin
.... .... 123, 145 35, 55 111

And just use Array where you need. I guess its opinion based, but it somehow makes sense to me, to keep them inside the entity. Have you tought about this?

webdeb avatar Jan 13 '20 00:01 webdeb

Related: https://github.com/hasura/graphql-engine/issues/1919

tirumaraiselvan avatar May 11 '20 07:05 tirumaraiselvan

Hey @tirumaraiselvan, any ETAs on this feature? This would reduce joins needed to make queries, thus improving performance tremendously.

almassapargali avatar Oct 15 '20 19:10 almassapargali

I agree, is there any info about that ?

brunettia avatar Nov 12 '20 12:11 brunettia

We manage our permissions in Open Policy Agent (OPA), and this would be great for us in "feature" permissions (eg. does "user1" have the permission "show-reports"). Currently if we want to enforce we have to:

  1. Make OPA enumerate the permissions of the users.
  2. Persist the result in a Postgres table: (user_id, permission_id).
  3. Do a Hasura permission with _exists to check the table with user_id=x-hasura-user-id and permission_id="show-reports".

If we could put the OPA result in the session instead and check directly if it includes a certain permission_id, we would avoid the need for point 2 and probably would be more performant as well.

mdemierre avatar Nov 19 '20 10:11 mdemierre

It's a bit frustrating that feature which would make many authorization patterns easier doesn't get much attention. Is there any plan to include it in the roadmap?

DavidKvas avatar Feb 08 '22 10:02 DavidKvas

We are definitely considering working on this. The exact ETAs are hard to give at the moment but this is a feature we would definitely like to provide.

tirumaraiselvan avatar Feb 08 '22 12:02 tirumaraiselvan

cc @tirumaraiselvan

Hey folks, I will be very interested in this feature as well, it would greatly simplify our authorization pattern.

I do something along these line currently :

/* HASURA : permissions */

// x-hasura-user-permissions 
-> ['users:view', 'users:invite']

// tables_permissions (with array of permission for each table action)

| table   | insert           | select         | update           | Delete                             |
|---------|------------------|----------------|------------------|------------------------------------|
| 'users' | ['users:invite'] | ['users:view'] | ['users:modify'] | ['users:archive', 'users:suspend'] |

// table: users, action: select
{
    "_exists": {
      "_table": { "schema": "public", "name": "tables_permissions" },
      "_where": {
        "_and": [
          { "table":  { "_eq": "users" } },
          { "select": { "_in": ["x-hasura-user-permissions"] } }
        ]
      }
    }
}

bduron avatar Feb 11 '22 17:02 bduron

@coco98 @tirumaraiselvan , this is definitely a high priority concern / blocker for our organization as well. We would love to see this on the roadmap and I'm sure it would help other orgs make it through the InfoSec gates where role based auth isn't sufficient.

dorianiq avatar Mar 07 '22 04:03 dorianiq

@coco98 @tirumaraiselvan still very high priority concern as well for my team, LHS session variable would really unleash the full power of ABAC rules for Hasura 💪

bduron avatar Mar 22 '22 22:03 bduron

We are also interested in this one. We are using open policy agent and having permissions in hasura is not what we desire.

zmitry avatar May 26 '22 10:05 zmitry

This is currently a blocker for us, we might end up giving up on Hasura due to this. This feature would simplify things so much.

Nilotaviano avatar Jun 23 '22 20:06 Nilotaviano

Hasura, please start working on this. It can't be that hard and would simplify our authorization flow IMMENSLY !

maaft avatar Jan 13 '23 17:01 maaft

Any update on this?

vntrungld avatar Mar 03 '23 07:03 vntrungld

Hi Hasura, are you considering working on this?

james075 avatar Jul 31 '23 15:07 james075