Metadata API Reference: Permissions
Introduction
The permission layer is designed to restrict the operations that can be
performed by various users. Permissions can be defined on various
operations (insert/select/update/delete) at a role level granularity. By
default, the admin
role has unrestricted access to all operations.
All X-Hasura-*
header values can be used in the permission rules.
These values can come with the request and can be validated using
webhook or can be sent with the JWT token.
The metadata API is supported for versions v2.0.0
and above and
replaces the older schema/metadata API.
pg_create_insert_permission
An insert permission is used to enforce constraints on the data that is being inserted.
Let's look at an example, a permission for the user
role to insert
into the article
table. What is the constraint that we would like to
enforce here? A user can only insert articles for themselves .
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_insert_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"check" : {
"author_id" : "X-HASURA-USER-ID"
},
"set":{
"id":"X-HASURA-USER-ID"
},
"columns":["name","author_id"]
}
}
}
This reads as follows - for the user
role:
- For every row that is being inserted into the article table, allow
insert only if the
check
passes i.e. that theauthor_id
column value is the same as the value in the request headerX-HASURA-USER-ID
". - If the above
check
passes, then access for insert will be limited to columnsname
andauthor_id
only. - When this insert happens, the value of the column
id
will be automaticallyset
to the value of the resolved session variableX-HASURA-USER-ID
.
The argument for check
is a boolean expression which has the same
syntax as the where
clause in the select
query, making it extremely
expressive.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_insert_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"check" : {
"author_id" : "X-HASURA-USER-ID",
"$or" : [
{
"category" : "editorial",
"is_reviewed" : false
},
{
"category" : { "$neq" : "editorial"}
}
]
}
}
}
}
In the above definition, the row is allowed to be inserted if the
author_id
is the same as the request's user id and is_reviewed
is
false
when the category
is "editorial".
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | InsertPermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_drop_insert_permission
The pg_drop_insert_permission
API is used to drop an existing insert
permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_drop_insert_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_create_select_permission
A select permission is used to restrict access to only the specified columns and rows.
Let's look at an example, a permission for the user
role to select
from the article
table: all columns can be read, as well as the rows
that have been published or authored by the user themselves.
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_select_permission",
"args" : {
"table" : "article",
"role" : "user",
"source": "default",
"permission" : {
"columns" : "*",
"filter" : {
"$or" : [
{ "author_id" : "X-HASURA-USER-ID" },
{ "is_published" : true }
]
},
"limit": 10,
"allow_aggregations": true
}
}
}
This reads as follows - For the user
role:
- Allow selecting rows where the
check
passes i.e.is_published
istrue
or theauthor_id
matches the value of the session variableX-HASURA-USER-ID
. - Allow selecting all columns (because the
columns
key is set to*
). limit
the numbers of rows returned by a query to thearticle
table by theuser
role to a maximum of 10.- Allow aggregate queries.
- All query and subscription root fields are enabled.
Let's take another example to show how to enable a particular set of root fields.
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_select_permission",
"args" : {
"table" : "article",
"role" : "guest",
"source": "default",
"permission" : {
"columns" : "*",
"filter" : {},
"query_root_fields": ["select_by_pk"],
"subscription_root_fields": ["select_by_pk"]
}
}
}
This reads as follows - for the guest
role:
- Allow access to all the rows.
- Allow selecting all the columns.
- Allow only the
select_by_pk
root field in thequery
andsubscription
root fields. The other root fields will be disabled.
The select permission of the guest
role is configured in a way such that, it can:
- The access to the
article
table is restricted to what can be accessed through relationships to thearticle
table. - If the
guest
has the access to the primary key value, it can access the data corresponding to that primary key.
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | SelectPermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_drop_select_permission
The pg_drop_select_permission
is used to drop an existing select
permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_drop_select_permission",
"args" : {
"table" : "article",
"role" : "user",
"source": "default"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_create_update_permission
An update permission is used to restrict the columns and rows that can be updated. Its structure is quite similar to the select permission.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_update_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"columns" : ["title", "content", "category"],
"filter" : {
"author_id" : "X-HASURA-USER-ID"
},
"check" : {
"content" : {
"_ne": ""
}
},
"set":{
"updated_at" : "NOW()"
}
}
}
}
This reads as follows - for the user
role:
- Allow updating only those rows where the
filter
passes i.e. the value of theauthor_id
column of a row matches the value of the session variableX-HASURA-USER-ID
. - If the above
filter
passes for a given row, allow updating only thetitle
,content
andcategory
columns (as specified in thecolumns
key). - After the update happens, verify that the
check
condition holds for the updated row i.e. that the value in thecontent
column is not empty. - When this update happens, the value of the column
updated_at
will be automaticallyset
to the current timestamp.
It is important to deny updates to columns that will determine the row
ownership. In the above example, the author_id
column determines the
ownership of a row in the article
table. Columns such as this should
never be allowed to be updated.
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | UpdatePermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_drop_update_permission
The pg_drop_update_permission
API is used to drop an existing update
permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_drop_update_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_create_delete_permission
A delete permission is used to restrict the rows that can be deleted.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_create_delete_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"filter" : {
"author_id" : "X-HASURA-USER-ID"
}
}
}
}
This reads as follows:
"delete
for the user
role on the article
table is allowed on rows
where author_id
is the same as the request header X-HASURA-USER-ID
value."
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | DeletePermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_drop_delete_permission
The pg_drop_delete_permission
API is used to drop an existing delete permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "pg_drop_delete_permission",
"args" : {
"table" : "article",
"role" : "user",
"source": "default"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
pg_set_permission_comment
pg_set_permission_comment
is used to set/update the comment on a permission. Setting the comment to null
removes it.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: admin
{
"type": "pg_set_permission_comment",
"args": {
"table": "article",
"source": "default",
"role": "user",
"type" : "update",
"comment" : "can only modify their own rows"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | The role in the permission |
type | true | permission type (one of select/update/delete/insert) | The type of the permission |
comment | false | Text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_create_insert_permission
An insert permission is used to enforce constraints on the data that is being inserted.
Let's look at an example, a permission for the user
role to insert
into the article
table. What is the constraint that we would like to
enforce here? A user can only insert articles for themselves .
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_create_insert_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"check" : {
"author_id" : "X-HASURA-USER-ID"
},
"set":{
"id":"X-HASURA-USER-ID"
},
"columns":["name","author_id"]
}
}
}
This reads as follows - for the user
role:
- For every row that is being inserted into the article table, allow
insert only if the
check
passes i.e. that theauthor_id
column value is the same as the value in the request headerX-HASURA-USER-ID
". - If the above
check
passes, then access for insert will be limited to columnsname
andauthor_id
only. - When this insert happens, the value of the column
id
will be automaticallyset
to the value of the resolved session variableX-HASURA-USER-ID
.
The argument for check
is a boolean expression which has the same
syntax as the where
clause in the select
query, making it extremely
expressive.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_create_insert_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"check" : {
"author_id" : "X-HASURA-USER-ID",
"$or" : [
{
"category" : "editorial",
"is_reviewed" : false
},
{
"category" : { "$neq" : "editorial"}
}
]
}
}
}
}
In the above definition, the row is allowed to be inserted if the
author_id
is the same as the request's user id and is_reviewed
is
false
when the category
is "editorial".
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | InsertPermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_drop_insert_permission
The mssql_drop_insert_permission
API is used to drop an existing insert permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_drop_insert_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_create_select_permission
A select permission is used to restrict access to only the specified columns and rows.
Let's look at an example, a permission for the user
role to select
from the article
table: all columns can be read, as well as the rows
that have been published or authored by the user themselves.
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_create_select_permission",
"args" : {
"table" : "article",
"role" : "user",
"source": "default",
"permission" : {
"columns" : "*",
"filter" : {
"$or" : [
{ "author_id" : "X-HASURA-USER-ID" },
{ "is_published" : true }
]
},
"limit": 10,
"allow_aggregations": true
}
}
}
This reads as follows - For the user
role:
- Allow selecting rows where the
check
passes i.e.is_published
istrue
or theauthor_id
matches the value of the session variableX-HASURA-USER-ID
. - Allow selecting all columns (because the
columns
key is set to*
). limit
the numbers of rows returned by a query to thearticle
table by theuser
role to a maximum of 10.- Allow aggregate queries.
- All query and subscription root fields are enabled.
Let's take another example to show how to enable a particular set of root fields.
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_create_select_permission",
"args" : {
"table" : "article",
"role" : "guest",
"source": "default",
"permission" : {
"columns" : "*",
"filter" : {},
"query_root_fields": ["select_by_pk"],
"subscription_root_fields": ["select_by_pk"]
}
}
}
This reads as follows - for the guest
role:
- Allow access to all the rows.
- Allow selecting all the columns.
- Allow only the
select_by_pk
root field in thequery
andsubscription
root fields. The other root fields will be disabled.
The select permission of the guest
role is configured in a way such that, it can:
- The access to the
article
table is restricted to what can be accessed through relationships to thearticle
table. - If the
guest
has the access to the primary key value, it can access the data corresponding to that primary key.
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | SelectPermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_drop_select_permission
The mssql_drop_select_permission
is used to drop an existing select permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_drop_select_permission",
"args" : {
"table" : "article",
"role" : "user",
"source": "default"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_create_update_permission
An update permission is used to restrict the columns and rows that can be updated. Its structure is quite similar to the select permission.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_create_update_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"columns" : ["title", "content", "category"],
"filter" : {
"author_id" : "X-HASURA-USER-ID"
},
"check" : {
"content" : {
"_ne": ""
}
},
"set":{
"updated_at" : "NOW()"
}
}
}
}
This reads as follows - for the user
role:
- Allow updating only those rows where the
filter
passes i.e. the value of theauthor_id
column of a row matches the value of the session variableX-HASURA-USER-ID
. - If the above
filter
passes for a given row, allow updating only thetitle
,content
andcategory
columns (as specified in thecolumns
key). - After the update happens, verify that the
check
condition holds for the updated row i.e. that the value in thecontent
column is not empty. - When this update happens, the value of the column
updated_at
will be automaticallyset
to the current timestamp.
It is important to deny updates to columns that will determine the row
ownership. In the above example, the author_id
column determines the
ownership of a row in the article
table. Columns such as this should
never be allowed to be updated.
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | UpdatePermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_drop_update_permission
The mssql_drop_update_permission
API is used to drop an existing
update permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_drop_update_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_create_delete_permission
A delete permission is used to restrict the rows that can be deleted.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_create_delete_permission",
"args" : {
"table" : "article",
"source": "default",
"role" : "user",
"permission" : {
"filter" : {
"author_id" : "X-HASURA-USER-ID"
}
}
}
}
This reads as follows:
"delete
for the user
role on the article
table is allowed on rows
where author_id
is the same as the request header X-HASURA-USER-ID
value."
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
permission | true | DeletePermission | The permission definition |
comment | false | text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_drop_delete_permission
The mssql_drop_delete_permission
API is used to drop an existing
delete permission for a role on a table.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin
{
"type" : "mssql_drop_delete_permission",
"args" : {
"table" : "article",
"role" : "user",
"source": "default"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | Role |
source | false | SourceName | Name of the source database of the table (default: default ) |
mssql_set_permission_comment
mssql_set_permission_comment
is used to set/update the comment on a permission. Setting the comment to null
removes it.
An example:
POST /v1/metadata HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: admin
{
"type": "mssql_set_permission_comment",
"args": {
"table": "article",
"source": "default",
"role": "user",
"type" : "update",
"comment" : "can only modify their own rows"
}
}
Args syntax
Key | Required | Schema | Description |
---|---|---|---|
table | true | TableName | Name of the table |
role | true | RoleName | The role in the permission |
type | true | permission type (one of select/update/delete/insert) | The type of the permission |
comment | false | Text | Comment |
source | false | SourceName | Name of the source database of the table (default: default ) |