hasura / hasura/graphql-engine

Feature request: reusable permission fragments

Open
#6,992 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
32.1k
Forks
3k
PR merge metrics
PR metrics pending

Description

I asked @coco98 a little bit about this in the May Community Call, but thought I should expand a little bit on some of our use cases here.

Our product is a multi-tenant application for running virtual conferences. Each virtual conference has a number of video chat rooms. A room can be public - in which case any attendee at the conference can see it - or they can be private - in which case only 'members' of that specific room can see it.

The fragment of permissions logic that implements this looks something like:

```yaml
- _or:
- managementModeName:
_eq: PUBLIC
- roomPeople:
registrant:
userId:
_eq: X-Hasura-User-Id
```

However, this permissions logic is not only needed for the `Room` table. It's also used for controlling access to multiple other related tables. Here are some examples from our metadata:

* To control access to [an analytics table](https://github.com/clowdr-app/clowdr/blob/56bcbe10de2c37fe05f81a6b5d5d03e81bda9b4c/hasura/metadata/tables.yaml#L338)
* To control access to [the text chat](https://github.com/clowdr-app/clowdr/blob/56bcbe10de2c37fe05f81a6b5d5d03e81bda9b4c/hasura/metadata/tables.yaml#L457) associated with the room
* To control access to [the video session](https://github.com/clowdr-app/clowdr/blob/56bcbe10de2c37fe05f81a6b5d5d03e81bda9b4c/hasura/metadata/tables.yaml#L6058) associated with the room

And so on.

What concerns me at the moment is that each of these separate pieces of code implements the same 'business rule' - i.e. that everyone can access public rooms and only specific people can access non public rooms. But the implementation is simply copy-pasted across the metadata, making it quite unmaintanable.

What if the rule changes (e.g. we add a new room mode that has different business logic for access control)? Then we have to comb through the metadata looking for instances of this logic and manually updating it. This is error prone and you can probably imagine that the logic is likely to get out of sync over time, compromising application security.

What I would really like to be able to do is define this fragment of logic once, in a central place. Then I would like to just call into that logic from each place where it is needed. When the central definition changes, it is immediately reflected across every table that uses it.

Hopefully this is an illustrative example! I could definitely pull out many more from our codebase. For example, we flatten our RBAC permissions into a single view and then perform lookups against that. Rather than writing [a large (and nearly identical) multi-armed `_exists` query](https://github.com/clowdr-app/clowdr/blob/56bcbe10de2c37fe05f81a6b5d5d03e81bda9b4c/hasura/metadata/tables.yaml#L6191) for each table to look up these permissions, it would be super nice to be able to just define and call something like `has_permission(PERMISSION_NAME, userId)`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.