graphql-engine
graphql-engine copied to clipboard
Create permission check with a session variable in the LHS
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):

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.

Curious if you all have already considered a feature like this?
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?
Related: https://github.com/hasura/graphql-engine/issues/1919
Hey @tirumaraiselvan, any ETAs on this feature? This would reduce joins needed to make queries, thus improving performance tremendously.
I agree, is there any info about that ?
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:
- Make OPA enumerate the permissions of the users.
- Persist the result in a Postgres table:
(user_id, permission_id)
. - Do a Hasura permission with
_exists
to check the table withuser_id=x-hasura-user-id
andpermission_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.
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?
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.
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"] } }
]
}
}
}
@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.
@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 💪
We are also interested in this one. We are using open policy agent and having permissions in hasura is not what we desire.
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.
Hasura, please start working on this. It can't be that hard and would simplify our authorization flow IMMENSLY !
Any update on this?
Hi Hasura, are you considering working on this?