Description
Version Information
Server Version: v2.46.0-cloud.1
Environment
Hasura Cloud
What is the current behaviour?
When querying a table using a role that inherits from another inherited role (i.e., a "nested inherited role"), the permissions are not applied as expected. Specifically, the row-level and column-level restrictions defined in the base inherited role are ignored, and the nested inherited role gains unrestricted access to all columns and rows, even when it should inherit the more restrictive permissions.
For example:
- A base inherited role (
base_role
) combines permissions from multiple roles, including a role (reader_role
) with a row filter (e.g.,{"id": "X-Hasura-User-Id"}
) and limited column access (e.g., includes an additional columnrestricted_field
). - When querying directly with
base_role
, the permissions work as expected: only the row matching the session variable is returned with therestricted_field
column, and other rows exclude this column. - However, when querying with a nested inherited role (
nested_role
) that inheritsbase_role
and another role with no additional permissions on the table, the row filter and column restrictions are bypassed, and all rows include therestricted_field
column.
This behavior contradicts the expected permission inheritance logic outlined in the Hasura documentation for inherited roles.
What is the expected behaviour?
The nested inherited role (nested_role
) should inherit the permissions of the base inherited role (base_role
) correctly, including all row filters and column restrictions. Based on the documentation under "How the permissions of the inherited role are interpreted," the nested role should:
- Apply the row filter (e.g.,
{"id": "X-Hasura-User-Id"}
) fromreader_role
viabase_role
. - Restrict access to the
restricted_field
column to only the rows where the filter evaluates totrue
, returningnull
for that column in all other rows, as described in the "Accessibility of a field for an inherited role" section.
In short, querying with nested_role
should yield the same restricted results as querying with base_role
, unless explicitly overridden.
How to reproduce the issue?
-
Set up a table and roles:
- Create a table
users
with columns:id
(Int, PK),name
(Text),restricted_field
(Text). - Define a
public
role with select permissions:- Columns:
id
,name
- No row filter (all rows accessible).
- Columns:
- Define a
reader_role
with select permissions:- Columns:
id
,name
,restricted_field
- Row filter:
{"id": "X-Hasura-User-Id"}
.
- Columns:
- Create an inherited role
base_role
that inherits frompublic
andreader_role
. - Create a nested inherited role
nested_role
that inherits frombase_role
and another role (e.g.,writer_role
) with no permissions defined on theusers
table.
- Create a table
-
Test with
base_role
:- Query the
users
table with:POST /v1/graphql HTTP/1.1 Content-Type: application/json X-Hasura-Role: base_role X-Hasura-User-Id: 1
query { users { id name restricted_field } }
- Expected and observed result: Row with
id: 1
includesrestricted_field
, other rows exclude it (or shownull
).
- Query the
-
Test with
nested_role
:- Query the
users
table with:POST /v1/graphql HTTP/1.1 Content-Type: application/json X-Hasura-Role: nested_role X-Hasura-User-Id: 1
query { users { id name restricted_field } }
- Expected result: Same as
base_role
(rowid: 1
showsrestricted_field
, others shownull
). - Observed result: All rows include
restricted_field
, ignoring the row filter.
- Query the
Screenshots or Screencast
Screen.Recording.2025-03-27.at.12.12.38.PM.mov
Keywords
- Inherited roles
- Nested inherited roles
- Permission inheritance
- Row filter bypass
- Column access restriction
- Hasura role permissions