mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-23 23:43:44 +03:00
123 lines
4.7 KiB
Plaintext
123 lines
4.7 KiB
Plaintext
|
Modelling Roles in Hasura
|
||
|
=========================
|
||
|
|
||
|
.. contents:: Table of contents
|
||
|
:backlinks: none
|
||
|
:depth: 2
|
||
|
:local:
|
||
|
|
||
|
.. TODO: Move this to roles-variables page
|
||
|
|
||
|
General guidelines for modelling roles in Hasura.
|
||
|
|
||
|
Flat, non-hierarchical roles
|
||
|
----------------------------
|
||
|
|
||
|
Roles can be typically be modeled in two ways:
|
||
|
|
||
|
1. **Hierarchical roles**: Access scopes are nested depending on available roles. `Roles in Github for organisations <https://help.github.com/en/articles/managing-peoples-access-to-your-organization-with-roles>`_
|
||
|
is a great example of such modelling where access scopes are inherited by deeper roles:
|
||
|
|
||
|
.. thumbnail:: ../../../../img/graphql/manual/auth/github-org-hierarchical-roles.png
|
||
|
|
||
|
2. **Flat roles**: Non-hierarchical roles with each role requiring an independent access scope to be defined.
|
||
|
|
||
|
Roles in Hasura have to be defined in the latter way i.e. in a **flat, non-hierarchical model**.
|
||
|
|
||
|
To convert the above hierarchical roles model into the one expected by Hasura, you will need to model roles as
|
||
|
partially captured by the table below (*showing access permissions for the* ``user`` *&* ``org-member`` *roles*,
|
||
|
``repositories`` *table and* ``select`` *operation*):
|
||
|
|
||
|
.. list-table::
|
||
|
:header-rows: 1
|
||
|
:widths: 25 20 45
|
||
|
|
||
|
* - Role
|
||
|
- Access Permissions
|
||
|
- Example permission rule
|
||
|
|
||
|
* - user
|
||
|
- Allow access to personally created repositories
|
||
|
-
|
||
|
.. code-block:: json
|
||
|
|
||
|
{
|
||
|
"creator_id": {
|
||
|
"_eq": "X-Hasura-User-Id"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
* - org-member
|
||
|
- Allow access to personally created repositories and the organisation's repositories.
|
||
|
-
|
||
|
.. code-block:: json
|
||
|
|
||
|
{
|
||
|
"_or": [
|
||
|
{
|
||
|
"creator_id": {
|
||
|
"_eq": "X-Hasura-User-Id"
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
"organization": {
|
||
|
"members": {
|
||
|
"member_id" : {
|
||
|
"_eq" : "X-Hasura-User-Id"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
|
||
|
Making role-based user information available
|
||
|
--------------------------------------------
|
||
|
|
||
|
Effective permission rules require that information about which roles have access to which objects is available
|
||
|
when processing the permission rule. Different users with the same role or the same user with different roles
|
||
|
may have access to different sets of rows of the same table.
|
||
|
|
||
|
In some cases this is straightforward - for example, to restrict access for authors to only their articles, a
|
||
|
trivial row-level permission like ``"creator_id": {"_eq": "X-Hasura-User-Id"}`` will suffice. In others, like
|
||
|
our example in the previous section, this user information (*ownership or relationship*) must be available for
|
||
|
defining a permission rule.
|
||
|
|
||
|
These non-trivial use-cases are to handled differently based on whether this information is available in the same
|
||
|
database or not.
|
||
|
|
||
|
Relationship information is available in the same database
|
||
|
##########################################################
|
||
|
|
||
|
Let's take a closer look at the permission rule for the ``org-member`` rule in the example from the previous
|
||
|
section. The rule reads as "*allow access to this repository if it was created by this user or if this user is
|
||
|
a member of the organisation that this repository belongs to*".
|
||
|
|
||
|
The crucial piece of user information, that is presumed to be available in the same database, that makes this an
|
||
|
effective rule is the mapping of users (*members*) to organizations.
|
||
|
|
||
|
Since this information is available in the same database, it can be easily leveraged via
|
||
|
:ref:`Relationships in permissions <relationships-in-permissions>` (*see this reference for another
|
||
|
example of the same kind*).
|
||
|
|
||
|
Relationship information is **not** available in the same database
|
||
|
##################################################################
|
||
|
|
||
|
When this user information is not available in the database that Hasura is configured to use, session variables
|
||
|
are the only avenue to pass this information to a permission rule. In our example, the mapping of users (members)
|
||
|
to organizations may not have been in available in the same database.
|
||
|
|
||
|
To convey this information, a session variable, say ``X-Hasura-Allowed-Organisations`` can be used by the
|
||
|
configured authentication to relay this information. We can then check for the following condition to emulate
|
||
|
the same rule - *is the organization that this repository belongs to part of the list of the organizations the
|
||
|
user is a member of*.
|
||
|
|
||
|
.. admonition:: Arrays in permission rules
|
||
|
|
||
|
The ability to use arrays and operators like ``contains`` or ``contained_by`` are currently work-in-progress
|
||
|
and will be available soon.
|
||
|
|
||
|
|
||
|
|
||
|
|