docs/docs/auth/authorization/permissions/disabling-root-fields.mdx
import Thumbnail from '@site/src/components/Thumbnail'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
Sometimes you may want a role to only have access to certain root fields of a table or have the table only be accessible through a relationship.
When you track a table in Hasura Engine, all the GraphQL root fields available to the role are exposed. Ie: Under
the query root field: select, select_by_pk and select_aggregate are exposed. Under the subscription
root field, select, select_by_pk, select_aggregate and select_stream are exposed. Root field visibility can
disable specific query and subscription root fields.
:::info Supported from
Root field visibility is supported in version v2.8.0 and above.
:::
<Tabs groupId="user-preference" className="api-tabs"> <TabItem value="console" label="Console">You can disable specific root fields for queries and subscriptions by unchecking them in the Select permission for the table and role in Console. This is located in the Console under **Data -> {table} -> Permissions -> {role} -> select -> Root fields permissions **
<Thumbnail src="/img/auth/disable-root-fields_console_2.11.1.png" alt="Disable root fields in Hasura Console" width="600px" />
</TabItem> <TabItem value="cli" label="CLI">You can disable root fields for queries and subscriptions specifying which are available for the select_permissions by
updating the specific metadata -> databases -> [database-name] -> tables -> [table-name].yaml file eg:
table:
name: users
schema: public
select_permissions:
- role: user
permission:
columns:
- id
filter: {}
query_root_fields:
- select_by_pk
subscription_root_fields:
- select
- select_by_pk
- select_aggregate
delete_permissions:
- role: user
permission:
backend_only: true
filter: {}
:::tip Nulls and empty arrays
Setting the value of query_root_fields or subscription_root_fields to null or not defining it at all implies that
all fields are allowed and an empty array means no fields are allowed.
:::
</TabItem> <TabItem value="api" label="API">You can disable root fields for Select permissions with the
permissions Metadata API by specifying which should be available in
the query_root_fields and subscription_root_fields arrays, eg:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_select_permission",
"args" : {
"table" : "users",
"role" : "user",
"source": "default",
"permission" : {
"columns" : "*",
"filter" : {
"is_public": true
},
"query_root_fields": ["select_by_pk"],
"subscription_root_fields": ["select", "select_by_pk"]
}
}
}
:::tip Nulls and empty arrays
Setting the value of query_root_fields or subscription_root_fields to null or not defining it at all implies that
all fields are allowed and an empty array means no fields are allowed.
:::
</TabItem> </Tabs>Let's say we have two tables, categories and products defined as follows:
| Table | Columns | Relationships |
|---|---|---|
| categories | id, name | products (array relationship) |
| products | id, name, description, price | category (object relationship) |
We would like to configure permissions of the guest role such that they are only able to access the products of the
categories which they can access i.e. access the products table only through the categories -> products
relationship.
Modifying the select permission of the products table:
<Thumbnail src="/img/auth/disable-all-root-fields_console_2.11.1.png" alt="Disable root fields in Hasura Console" width="600px" />
Now that no query_root_fields or subscription_root_fields are enabled, the guest role won't be able to access
the products table directly and can only access the products table through the categories -> products
relationship.
<Thumbnail src="/img/auth/authorization_root-field-visibility-api-query_2-16.png" alt="Query with disabled root fields" />
:::warning Row permission considerations
If root fields are disabled then you may want to simplify the row filter permissions by giving it "without any checks"
access to all rows. But you should be cautious here because the field may be accessible through a different type e.g.
the returning field in a mutation output type.
:::
Let's say you want to allow a client to fetch data from a table only if the client knows the primary key of a row in that table.
In this case, regardless of the permission on the table, only <table>_by_pk should be exposed in query_root.
<Thumbnail src="/img/auth/disable-select-root-fields_console_2.11.1.png" alt="Disable select root fields in Hasura Console" width="600px" />
Allow a role to only be able to make query and not subscription requests.
<Thumbnail src="/img/auth/disable-subscription-root-fields_console_2.11.1.png" alt="Disable subscription root fields in Hasura Console" width="600px" />