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

InsertPermission

Key Required Schema Description
check true BoolExp This expression has to hold true for every new row that is inserted

drop_insert_permission

Drop an existing insert permission for a role on a table.

Syntax

Key Required Schema Description
table true TableName Name of the table
role true RoleName Role

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:

  1. Allow all columns (because of *).
  2. Allow rows where is_published is true or the 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 SelectPermission The permission definition
comment false text comment

SelectPermission

Key Required Schema Description
columns true PGColumn array (or) '*' Only these columns are selectable (or all when '*' is specified)
filter true BoolExp Only the rows where this expression holds true are selectable

drop_select_permission

Drop an existing select permission for a role on a table.

Syntax

Key Required Schema Description
table true TableName Name of the table
role true RoleName Role

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:

  1. Allow only the columns : title, content and category to be updated
  2. 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

UpdatePermission

Key Required Schema Description
columns true PGColumn array Only these columns are updatable
filter true BoolExp Only the rows where this expression holds true are deletable

drop_update_permission

Drop an existing update permission for a role on a table.

Syntax

Key Required Schema Description
table true TableName Name of the table
role true RoleName Role

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

DeletePermission

Key Required Schema Description
filter true BoolExp Only the rows where this expression holds true are deletable

drop_delete_permission

Drop an existing delete permission for a role on a table.

Syntax

Key Required Schema Description
table true TableName Name of the table
role true RoleName Role

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"
    }
}

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