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_publishedistrueor theauthor_idis 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,contentandcategoryto be updated - Allow rows where
author_idis same as the one who is making the request,X-HASURA-USER-IDto 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"
}
}