diff --git a/modules/ROOT/pages/directives/index.adoc b/modules/ROOT/pages/directives/index.adoc index 0fcab321..a8929ad3 100644 --- a/modules/ROOT/pages/directives/index.adoc +++ b/modules/ROOT/pages/directives/index.adoc @@ -47,7 +47,7 @@ a| Required to differentiate interfaces that are used for relationship propertie | Used in combination with `@jwt`. Configures the JWT authentication and authorization filters to include an additional JWT claim which is either nested or using special characters not supported by GraphQL. -| `@subscriptionsAuthorization` +| xref::/security/subscriptions-authorization.adoc[`@subscriptionsAuthorization`] | Specifies authorization rules for subscriptions on the type. |=== diff --git a/modules/ROOT/pages/security/authorization.adoc b/modules/ROOT/pages/security/authorization.adoc index 91e2b11f..adb5aa1b 100644 --- a/modules/ROOT/pages/security/authorization.adoc +++ b/modules/ROOT/pages/security/authorization.adoc @@ -10,6 +10,12 @@ All authorization rules have an implied requirement for authentication, given th In the case of explicit authentication, configured using the `@authentication` directive, it is only ever evaluated during Cypher translation time. Unauthenticated requests with queries requiring authentication never reach the database. +[WARNING] +==== +The `@authorization` directive does not apply to subscriptions, it only applies to queries and mutations. +Instead, use xref::/security/subscriptions-authorization.adoc[`@subscriptionsAuthorization`] to configure the authorization for subscriptions if you intend to use subscriptions in your API and want the events protected. +==== + == Rules === Filtering diff --git a/modules/ROOT/pages/security/index.adoc b/modules/ROOT/pages/security/index.adoc index e20dfd70..49603558 100644 --- a/modules/ROOT/pages/security/index.adoc +++ b/modules/ROOT/pages/security/index.adoc @@ -8,6 +8,7 @@ auth/authorization/where.adoc, authentication-and-authorization/index.adoc * xref::/security/authentication.adoc[Authentication] - Explicit authentication, configured using the `@authentication` directive. * xref::/security/authorization.adoc[Authorization] - Authorization rules set using the `@authorization` directive. +* xref::/security/subscriptions-authorization.adoc[Subscriptions authorization] - Authorization rules for subscriptions set using the `@subscriptionsAuthorization` directive. * xref::/security/configuration.adoc[Configuration] - Instructions to set up instantiation. * xref::/security/impersonation-and-user-switching.adoc[Impersonation and user switching] - How to set up impersonation and user switching features. * xref::/security/operations.adoc[Operations] - Reference on GraphQL queries and how each location in each query triggers the evaluation of different authentication/authorization rules. diff --git a/modules/ROOT/pages/security/subscriptions-authorization.adoc b/modules/ROOT/pages/security/subscriptions-authorization.adoc new file mode 100644 index 00000000..cb0490f2 --- /dev/null +++ b/modules/ROOT/pages/security/subscriptions-authorization.adoc @@ -0,0 +1,65 @@ +[[subscriptions-authorization]] +:description: This page describes how to set up authorization features for subscriptions in the Neo4j GraphQL Library. += Subscriptions authorization + +Subscriptions require their own authorization rules, which are configured with the `@subscriptionsAuthorization` directive. +These rules are different to normal authorization rules because only filtering rules are available for subscriptions events and subscriptions events have more limitations in how they can be filtered. + +All subscriptions authorization rules have an implied requirement for authentication, given that the rules are normally evaluated against values in the JWT payload. + +== Rules + +=== Filtering + +Filtering rules prevent events which contain information that users don't have access to from reaching them - they will receive no indication that this is the case. +These rules are evaluated when the events are returned from the database, before they are broadcasted out to subscribing GraphQL clients. + +For instance, here is how to filter out `User` events which don't match the JWT of the user listening for events: + +[source, graphql, indent=0] +---- +type User @subscriptionsAuthorization(filter: [ + { where: { node: { id: "$jwt.sub" } } } +]) { + id: ID! +} +---- + +==== Events + +Filtering can be configured to only be performed on certain events: + +* `CREATED` +* `UPDATED` +* `DELETED` +* `RELATIONSHIP_CREATED` +* `RELATIONSHIP_DELETED` + +For instance, to only require filtering for mutations to a type itself and not its relationships: + +[source, graphql, indent=0] +---- +type User @subscriptionsAuthorization(filter: [ + { events: [CREATED, UPDATED, DELETED], where: { node: { id: "$jwt.sub" } } } +]) { + id: ID! +} +---- + +== 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 whilst other `Post` nodes are public, here is how to set this up: + +[source, graphql, indent=0] +---- +type Post @subscriptionsAuthorization(filter: [ + { requireAuthentication: false, where: { node: { public: true } } } +]) { + title: String! + content: String! + public: Boolean! +} +---- \ No newline at end of file