Graphql-engine: allow defining multiple (row + column) permission tuples for a given role + table + action

Created on 28 Nov 2019  路  6Comments  路  Source: hasura/graphql-engine

To restrict access to sensitive fields, the solution proposed in https://docs.hasura.io/1.0/graphql/manual/queries/control-access.html requires one to modify the db schema (creating a view and setting up new relationships/permissions)

Instead if it were possible to define multilple row + column permission rules this could be avoided.

e.g. For table user(id, name, email, phone), select permissions for role user can be

  • Rule 1:

    • Row permission: {} i.e. without any checks
    • Col permission: name
  • Rule 2:

    • Row permission: {id: {_eq: 'x-hasura-user-id'}} i.e. if user is the owner
    • Col permission: name, email, phone
auth server ideas

Most helpful comment

This is the exact need I had 2 days ago. I would solve this by moving sensitive & private data to a new table at the moment. However, if multiple rules for the same role in a table can be implemented, it will become easier to control & develop.

Current Solution
Also, even though I did a research about it, I couldn't reach the above documentation page which suggests creating a view by using:

Data -> SQL


CREATE VIEW user_public AS
  SELECT id, name, email
    FROM user_profile;

where the original fields of a user profile are:

user_profile (id, name, email, phone, address)

All 6 comments

This is the exact need I had 2 days ago. I would solve this by moving sensitive & private data to a new table at the moment. However, if multiple rules for the same role in a table can be implemented, it will become easier to control & develop.

Current Solution
Also, even though I did a research about it, I couldn't reach the above documentation page which suggests creating a view by using:

Data -> SQL


CREATE VIEW user_public AS
  SELECT id, name, email
    FROM user_profile;

where the original fields of a user profile are:

user_profile (id, name, email, phone, address)

Related to #877

My usecase is similar to this, but a bit more complex.

eg:

  • Rule 1:

    • Row permission: {} i.e. without any checks

    • Col permission: name

  • Rule 2:

    • Row permission: {id: {_eq: 'x-hasura-user-id'}} i.e. if user is the owner
    • Col permission: email
  • Rule 3:

    • Row permission: {permissions: {name: {_eq: "CAN_VIEW_PHONE"}}} i.e. if user has certain permissions linked to its user account
    • Col permission: phone

Ideally, all checks would be run and the union of all columns would be used as the final result.

eg: if the user id matches but the user does not have the CAN_VIEW_PHONE permission, then he would be allowed to access the columns: ["name", "email"]

We need this because our permissions that are linked to a certain role are configurable by the users of the system.
For now i think i'll just rewrite all permissions in hasura using the api when the permissions are modified by the user, since that shouldn't happen very frequently.

Guys let me get some attention to the small rfc I've created here https://github.com/hasura/graphql-engine/pull/5783 where I am touching exactly this problem, with a slightly other mindset. Instead of multiple rules, the idea is to define virtual roles
role + check + columns.

A virtual role is a role which a user has for this particular table, like I am the _author_ of this post. Or I am collaborator.

So instead of extending the single role capabilities with multiple rules inside a role, we ca have many virtual roles for the same table: a user can have different relationships to a table, like _author_, _owner_, _moderator_ etc.

To control which vrole should be used, we can use graphql query itself and the client should tell the engine _as_ who he is gonna to interact with the table. like user(_as: me) { my_private_info }

If you curious, please check out the rfc, maybe I could contribute to this and learn some haskell btw :)

The lack of this feature does not let me sleep well, so here another idea:

add a suffix to the role to define which rule you want to use:

Bildschirmfoto 2020-11-04 um 18 00 04

I am not sure how to best implement this. I guess the simplest would be just with the "x-hasura-role" Header, but you might want to use different rules on different tables so with the _as option it would be theoretically possible:

user(_as: "me") {
  balance

  projects(_as: "owner") {
    name
    costs
  }
}

would love to get some attention from you guys here: @rikinsk @tirumaraiselvan

because right now you have to create a separate view to support multiple permissions on the same table, instead of multiple rules on the same table

It's very cool that hasura supports views and functions, but using them to slice permissions is a workaround.

Was this page helpful?
0 / 5 - 0 ratings