Data API Reference: Permissions¶
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.
Note
The hasura API gateway
forwards X-Hasura-*
headers with each request to the data
microservice. So, when an API
call is made with an auth_token
representing some user, a variable called X-Hasura-User-Id
is updated with the
hasura_id
of the user and a variable called X-Hasura-Role
is updated with the role of the user making the call.
These variables can now be used to describe the access permissions for rows in tables. If the X-Hasura-Role
header is
passed with the request, its value is passed to the data
microservice if the user has that
particular role or else the request is rejected with a 403 Forbidden
response.
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 article
table. What is the constraint that we would like to enforce here? A user can only insert articles for themself
POST data.<cluster-name>.hasura-app.io/v1/query HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: <role> # optional. Pass if only specific user role has access
{
"type" : "create_insert_permission",
"args" : {
"table" : "article",
"role" : "user",
"permission" : {
"check" : {
"author_id" : "X-HASURA-USER-ID"
}
}
}
}
This reads as follows:
“For the user role, for every row that is being inserted into the article table, check that the author_id
column value is the same as the one who is making the request, X-HASURA-USER-ID
”
X-HASURA-USER-ID
is a special value that refers to the id of the user who made the request. It can only be used in place of a value of type integer/smallint/bigint in a boolean expression.
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. For example,
POST data.<cluster-name>.hasura-app.io/v1/query HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: <role> # optional. Pass if only specific user role has access
{
"type" : "create_insert_permission",
"args" : {
"table" : "article",
"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”.
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 |
drop_insert_permission¶
Drop an existing insert permission for a role on a table.
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 article
table: all columns can be read, and rows that have been published or authored by themself.
POST data.<cluster-name>.hasura-app.io/v1/query HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: <role> # optional. Pass if only specific user role has access
{
"type" : "create_select_permission",
"args" : {
"table" : "article",
"role" : "user",
"permission" : {
"columns" : "*",
"filter" : {
"$or" : [
{ "author_id" : "X-HASURA-USER-ID" },
{ "is_published" : true }
]
}
}
}
}
This reads as follows:
- Allow all
columns
(because of*
). - Allow rows where
is_published
istrue
or theauthor_id
is same as the one who is making the request,X-HASURA-USER-ID
.
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 |
drop_select_permission¶
Drop an existing select permission for a role on a table.
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 data.<cluster-name>.hasura-app.io/v1/query HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: <role> # optional. Pass if only specific user role has access
{
"type" : "create_update_permission",
"args" : {
"table" : "article",
"role" : "user",
"permission" : {
"columns" : ["title", "content", "category"],
"filter" : {
"author_id" : "X-HASURA-USER-ID"
}
}
}
}
This reads as follows:
- Allow only the
columns
:title
,content
andcategory
to be updated - Allow rows where
author_id
is same as the one who is making the request,X-HASURA-USER-ID
to be updated.
Note
It is important to deny updates to columns that will determine the row ownership. In the above example, author_id
column determines the ownership of a row in the article
table. Columns such as this should never be allowed to be updated.
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 |
drop_update_permission¶
Drop an existing update permission for a role on a table.
create_delete_permission¶
A delete permission is used to restrict the rows that can be deleted.
An example:
POST data.<cluster-name>.hasura-app.io/v1/query HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: <role> # optional. Pass if only specific user role has access
{
"type" : "create_delete_permission",
"args" : {
"table" : "article",
"role" : "user",
"permission" : {
"filter" : {
"author_id" : "X-HASURA-USER-ID"
}
}
}
}
This reads as follows:
“delete
for user
role on article
table is allowed on rows where author_id
is same as the one who is making the request, X-HASURA-USER-ID
.”
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 |
drop_delete_permission¶
Drop an existing delete permission for a role on a table.
set_permission_comment¶
set_permission_comment
is used to set/update the comment on a permission. Setting the comment to null
removes it.
An example:
POST /v1/query HTTP/1.1
Content-Type: application/json
Authorization: Bearer <auth-token> # optional if cookie is set
X-Hasura-Role: <role> # optional. Pass if only specific user role has access
{
"type": "set_permission_comment",
"args": {
"table": "article",
"role": "user",
"type" : "update",
"comment" : "can only modify his/her own rows"
}
}