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 `_ 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 ` (*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.