Root Field Visibility
Introduction
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.
Root field visibility is supported in version v2.8.0
and above.
- Console
- CLI
- API
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
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: {}
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.
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"]
}
}
}
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.
Root field visibility use cases
Allow a table to be accessible only through a relationship
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:
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.
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.
Access only via primary key
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
.
Disable subscription fields
Allow a role to only be able to make query and not subscription requests.