mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-17 20:41:49 +03:00
166 lines
5.9 KiB
Plaintext
166 lines
5.9 KiB
Plaintext
Access control use-cases
|
|
========================
|
|
|
|
.. contents:: Table of contents
|
|
:backlinks: none
|
|
:depth: 1
|
|
:local:
|
|
|
|
The following are the different permutations in which you can configure a single permission rule to support different use-cases.
|
|
|
|
|
|
Add a simple access control rule for a logged in user
|
|
-----------------------------------------------------
|
|
|
|
Let's say that we want to restrict users to fetch only their own data.
|
|
|
|
Head to the ``Permissions`` tab of the ``author`` table.
|
|
|
|
Now add a ``select`` access control rule for the ``user`` role on the ``author`` table:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/author-select-perms.png
|
|
|
|
This rule reads as:
|
|
|
|
.. list-table::
|
|
:header-rows: 1
|
|
:widths: 25 20 45
|
|
|
|
* - Definition
|
|
- Condition
|
|
- Representation
|
|
|
|
* - allow user to access only their own row
|
|
- ``id`` in the row is equal to ``user-id`` from the request session variable
|
|
-
|
|
.. code-block:: json
|
|
|
|
{
|
|
"id": {
|
|
"_eq": "X-Hasura-User-Id"
|
|
}
|
|
}
|
|
|
|
Now, let's make the same query as above but also include two dynamic authorization variables ``X-Hasura-Role`` and
|
|
``X-Hasura-User-Id`` via request headers. These will automatically get used according to the permission rule we set up.
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/query-with-perms.png
|
|
|
|
You can notice above how the same query now only includes the right slice of data.
|
|
|
|
.. admonition:: Defining access control rules
|
|
|
|
Access control, or permission rules can be as complex as you need them to be, even using a nested object's
|
|
fields if required. You can use the same operators that you use to filter query results to define
|
|
permission rules. See :doc:`filtering query results <../../queries/query-filters>` for more details.
|
|
|
|
For example, for an ``article`` table with a nested ``author`` table, we can define the select permission as:
|
|
|
|
.. code-block:: json
|
|
|
|
{
|
|
"_and":
|
|
[
|
|
{
|
|
"published_on": { "_gt": "31-12-2018" }
|
|
},
|
|
{
|
|
"author": {
|
|
"id": { "_eq": "X-Hasura-User-Id" }
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
This rule reads as: allow selecting an article if it was published after "31-12-2018" and its author is the current user.
|
|
|
|
.. _restrict_columns:
|
|
|
|
Restrict access to certain columns
|
|
----------------------------------
|
|
|
|
We can restrict the columns of a table that a particular role has access to.
|
|
|
|
Head to the ``Permissions`` tab of the table and edit the ``Select`` permissions for the role:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/restrict-columns.png
|
|
|
|
.. _limit_rows:
|
|
|
|
Limit number of rows returned in a single request
|
|
-------------------------------------------------
|
|
|
|
We can set a hard limit on the maximum number of rows that will be returned in a single request for a table for a particular role.
|
|
|
|
Head to the ``Permissions`` tab of the table and edit the ``Select`` permissions for the role:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/limit-results.png
|
|
|
|
|
|
.. _using-relationships-in-permissions:
|
|
|
|
Using relationships or nested objects in permissions
|
|
----------------------------------------------------
|
|
You can leverage relationships to define permission rules with fields from a nested object. Let's take the following example:
|
|
|
|
* An author/articles schema where an article can have one or more reviewers i.e. users with the role ``reviewer`` can only edit those articles that have been assigned to them:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/schema-for-nested-object-based-permissions.png
|
|
|
|
* The foreign key constraint from ``reviewers`` :: ``article_id`` → ``articles`` :: ``id`` is used for an array relationship called ``reviewers`` in the ``articles`` table:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/array-relationship-reviewers.png
|
|
:class: no-shadow
|
|
|
|
We can use this relationship in a permission rule for the ``articles`` table to limit access for users with the role ``reviewer`` to only assigned rows:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/nested-object-permissions-rule.gif
|
|
|
|
Via the relationship, we are using the ``reviewer_id`` field of the nested object ``reviewers`` in the the above permission rule that reads as "Allow updating an article if the **reviewer_id of any of the reviewers assigned to this article** is the same as the requesting user's id (*which is sent in the resolved session variable* ``X-Hasura-User-ID``)".
|
|
|
|
Let's say we have the following test data for the list of reviewers:
|
|
|
|
.. list-table:: Data in the ``reviewers`` table
|
|
:header-rows: 1
|
|
|
|
* - id
|
|
- article_id
|
|
- reviewer_id
|
|
* - 1
|
|
- 1
|
|
- 5
|
|
* - 2
|
|
- 3
|
|
- 5
|
|
* - 3
|
|
- 5
|
|
- 5
|
|
* - 4
|
|
- 2
|
|
- 6
|
|
* - 5
|
|
- 4
|
|
- 6
|
|
|
|
Applying the above permission rule for "update" to "select" operation also, let's query the ``articles`` table to watch this permission rule in action:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/restricted-data-for-role-reviewer.png
|
|
:class: no-shadow
|
|
|
|
As we've made this query with the role ``reviewer`` and user ID ``5`` (*highlighted in the request headers in the above image*), we can only query those articles for which this user is a reviewer. This will be the case for update mutations too. As the user with id ``5`` does not have access to article with id ``2`` (*refer to the table above*), the following mutation will not update any rows of the ``articles`` table:
|
|
|
|
.. thumbnail:: ../../../../img/graphql/manual/auth/unsuccessful-mutation-for-role-reviewer.png
|
|
:class: no-shadow
|
|
|
|
.. admonition:: Array and Object relationships work similarly
|
|
|
|
The above example would have worked even if the relationship were an object relationship. In our example, the corresponding rule for an object relationship would have read "*if this article's reviewer's id is the same as the requesting user's id, allow access to it*".
|
|
|
|
|
|
More about permissions
|
|
----------------------
|
|
|
|
Next: :doc:`Roles and dynamic variables <roles-variables>`
|
|
|
|
|