Metadata API Reference: Permissions¶
Table of contents
- Introduction
- pg_create_insert_permission
- pg_drop_insert_permission
- pg_create_select_permission
- pg_drop_select_permission
- pg_create_update_permission
- pg_drop_update_permission
- pg_create_delete_permission
- pg_drop_delete_permission
- pg_set_permission_comment
- mssql_create_insert_permission
- mssql_drop_insert_permission
- mssql_create_select_permission
- mssql_drop_select_permission
- mssql_create_update_permission
- mssql_drop_update_permission
- mssql_create_delete_permission
- mssql_drop_delete_permission
- mssql_set_permission_comment
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.
Variables in rules
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.
Supported from
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 checkpasses i.e. that theauthor_idcolumn value is the same as the value in the request headerX-HASURA-USER-ID”.
- If the above checkpasses, then access for insert will be limited to columnsnameandauthor_idonly.
- When this insert happens, the value of the column idwill be automaticallysetto 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 checkpasses i.e.is_publishedistrueor theauthor_idmatches the value of the session variableX-HASURA-USER-ID.
- Allow selecting all columns (because the columnskey is set to*).
- limitthe numbers of rows returned by a query to the- articletable by the- userrole to a maximum of 10.
- Allow aggregate queries.
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 filterpasses i.e. the value of theauthor_idcolumn of a row matches the value of the session variableX-HASURA-USER-ID.
- If the above filterpasses for a given row, allow updating only thetitle,contentandcategorycolumns (as specified in thecolumnskey).
- After the update happens, verify that the checkcondition holds for the updated row i.e. that the value in thecontentcolumn is not empty.
- When this update happens, the value of the column updated_atwill be automaticallysetto the current timestamp.
Note
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 his/her 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 checkpasses i.e. that theauthor_idcolumn value is the same as the value in the request headerX-HASURA-USER-ID”.
- If the above checkpasses, then access for insert will be limited to columnsnameandauthor_idonly.
- When this insert happens, the value of the column idwill be automaticallysetto 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 checkpasses i.e.is_publishedistrueor theauthor_idmatches the value of the session variableX-HASURA-USER-ID.
- Allow selecting all columns (because the columnskey is set to*).
- limitthe numbers of rows returned by a query to the- articletable by the- userrole to a maximum of 10.
- Allow aggregate queries.
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 filterpasses i.e. the value of theauthor_idcolumn of a row matches the value of the session variableX-HASURA-USER-ID.
- If the above filterpasses for a given row, allow updating only thetitle,contentandcategorycolumns (as specified in thecolumnskey).
- After the update happens, verify that the checkcondition holds for the updated row i.e. that the value in thecontentcolumn is not empty.
- When this update happens, the value of the column updated_atwill be automaticallysetto the current timestamp.
Note
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 his/her 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) | 
