Authorization
This is the documentation of the GraphQL Library version 6. For the long-term support (LTS) version 5, refer to GraphQL Library version 5 LTS. |
Authorization rules cover what specific data a generated Cypher query is allowed to access. They use predicates to evaluate the data accessed by the Cypher generated from a GraphQL query, thus allowing or disallowing execution within the context of nodes and their properties.
All authorization rules have an implied requirement for authentication, given that the rules are normally evaluated against values in the JWT payload.
In the case of explicit authentication, configured using the @authentication
directive, it is only evaluated during Cypher translation time.
Unauthenticated requests with queries requiring authentication never reach the database.
The |
Filtering rules
Filtering rules filter out data which users do not have access to, without throwing any errors. These rules are translated into filtering predicates, which are evaluated against matched data in the database.
Filtering rules protect data as well as obfuscate the information on the existence of that data to unauthorized users.
For instance, here is how to filter out Post
nodes which don’t belong to the current User
:
type User @node {
id: ID!
}
type Post @node @authorization(filter: [
{ where: { node: { author: { id_EQ: "$jwt.sub" } } } }
]) {
title: String!
content: String!
author: User! @relationship(type: "AUTHORED", direction: IN)
}
Operations
Filtering can be configured to only be performed on certain operations:
-
READ
-
AGGREGATE
-
UPDATE
-
DELETE
-
CREATE_RELATIONSHIP
-
DELETE_RELATIONSHIP
For instance, to only require filtering for the reading and aggregating posts:
type Post @node @authorization(filter: [
{ operations: [READ, AGGREGATE] where: { node: { author: { id_EQ: "$jwt.sub" } } } }
]) {
title: String!
content: String!
author: User! @relationship(type: "AUTHORED", direction: IN)
}
In case there is no |
Validating rules
Validating rules throw an error if a query is executed against data which users do not have access to.
These rules are evaluated in the database via filtering predicates containing calls to
apoc.util.validatePredicate
.
For instance, here is how to throw an error if a User
is accessed by anyone but the user themselves or an admin:
type JWT @jwt {
roles: [String!]!
}
type User @node @authorization(validate: [
{ where: { node: { id_EQ: "$jwt.sub" } } }
{ where: { jwt: { roles_INCLUDES: "admin" } } }
]) {
id: ID!
}
Operations
Validation can be configured to only be performed on certain operations:
-
READ
-
AGGREGATE
-
CREATE
-
UPDATE
-
DELETE
-
CREATE_RELATIONSHIP
-
DELETE_RELATIONSHIP
For instance, to only require validation for the update or deletion of a post:
type Post @node @authorization(validate: [
{ operations: [UPDATE, DELETE] where: { node: { author: { id_EQ: "$jwt.sub" } } } }
]) {
title: String!
content: String!
author: User! @relationship(type: "AUTHORED", direction: IN)
}
In case there is no |
Authorization without authentication
Authentication is implicitly required for every authorization check by default, but this can be disabled on a per-rule basis. This could be the case, for instance, when a node has a property which flags whether the node should be public or not.
For instance, in the case where some Post
nodes are private and belong to a particular User
, while other Post
nodes are public and readable by any user, here is how to set this up:
type User @node {
id: ID!
}
type Post @node @authorization(filter: [
{ where: { node: { author: { id_EQ: "$jwt.sub" } } } }
{ requireAuthentication: false, operations: [READ], where: { node: { public_EQ: true } } }
]) {
title: String!
content: String!
public: Boolean!
author: User! @relationship(type: "AUTHORED", direction: IN)
}