Skip to content

Nested Inherited Roles Bypassing Column Select Permissions #10711

Open
@yoshiwarab

Description

@yoshiwarab

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 column restricted_field).
  • When querying directly with base_role, the permissions work as expected: only the row matching the session variable is returned with the restricted_field column, and other rows exclude this column.
  • However, when querying with a nested inherited role (nested_role) that inherits base_role and another role with no additional permissions on the table, the row filter and column restrictions are bypassed, and all rows include the restricted_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"}) from reader_role via base_role.
  • Restrict access to the restricted_field column to only the rows where the filter evaluates to true, returning null 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?

  1. 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).
    • Define a reader_role with select permissions:
      • Columns: id, name, restricted_field
      • Row filter: {"id": "X-Hasura-User-Id"}.
    • Create an inherited role base_role that inherits from public and reader_role.
    • Create a nested inherited role nested_role that inherits from base_role and another role (e.g., writer_role) with no permissions defined on the users table.
  2. 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 includes restricted_field, other rows exclude it (or show null).
  3. 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 (row id: 1 shows restricted_field, others show null).
    • Observed result: All rows include restricted_field, ignoring the row filter.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    c/serverRelated to serverk/bugSomething isn't workingv2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions