Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
[[authorization]]
:description: This page describes how to set up authorization features in the Neo4j GraphQL Library.
= Authorization

Authorization rules concern themselves with specific data which is executed against during a generated Cypher query.
They are evaluated via predicates in the Cypher generated from a GraphQL query, so they execute within the context of nodes and their properties.
Authorization rules cover what specific data a generated Cypher query is executed against.
They use predicates to evaluate 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.
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, is only ever evaluated
during Cypher translation time, and unauthenticated requests with queries requiring authentication
will never reach the database.
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.

== Rules

=== Filter
=== Filtering

Filter rules filter out data which users do not have access to, without throwing any errors. These rules
are evaluated in the database, with the rules translated into filter predicates and evaluated against matched data.
Filter rules are valuable because they protect your data as well as obfuscate the information on the _existence_ of
data to unauthorized users.
Filtering rules filter out data which users do not have access to, without throwing any errors.
These rules are evaluated in the database, then translated into filtering predicates that are evaluated against matched data.

For instance, to filter out `Post` nodes which don't belong to the current `User`:
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`:

[source, graphql, indent=0]
----
Expand All @@ -36,13 +36,13 @@ type Post @authorization(filter: [
}
----

=== Validate
=== Validating

Validate rules throw an error if a query executes against data which users do not have access to. These rules are
evaluated in the database via filtering predicates containing calls to
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
https://neo4j.com/docs/apoc/current/overview/apoc.util/apoc.util.validatePredicate/[`apoc.util.validatePredicate`].

For instance, to throw an error if a `User` is accessed by anyone but the user themselves or an admin:
For instance, here is how to throw an error if a `User` is accessed by anyone but the user themselves or an admin:

[source, graphql, indent=0]
----
Expand All @@ -58,12 +58,12 @@ type User @authorization(validate: [
}
----

== Authorization not requiring authentication
== Authorization without authentication

Authentication is implicitly required for every authorization check by default, but this can be disabled on a per-rule basis.
This might be desired perhaps if a node has a property which flags whether the node should be public or not.
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, `Post` nodes might be private and belong to a particular `User`, or be public and readable by any user:
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:

[source, graphql, indent=0]
----
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
[[impersonation-and-user-switching]]
:description: This page describes the impersonation and user switching features of the Neo4j GraphQL Library.
= Impersonation and user switching

Impersonation and user switching are features of the Neo4j database and driver which allow for query execution in a different context to the initial connection.

== Impersonation

Impersonation still authenticates with the database as the original configured user, but runs the query in the context of an impersonated user.
When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (home database, permissions, etc.).
When impersonating a user, the query is run within the complete security context of the impersonated user and not the authenticated user (home database, permissions etc).

An example of how to impersonate a different user per request can be found below. In this example, the user to impersonate is taken from a HTTP header `User`:
Consider the following an example of how to impersonate a different user per request.
Here the user to impersonate is taken from a HTTP header `User`:

.TypeScript
[%collapsible]
[.tabbed-example]
====

[.include-with-Typescript]
=====
[source, typescript, indent=0]
----
import { ApolloServer } from "@apollo/server";
Expand Down Expand Up @@ -52,11 +57,10 @@ const { url } = await startStandaloneServer(server, {

console.log(`🚀 Server ready at: ${url}`);
----
====
=====

.JavaScript
[%collapsible]
====
[.include-with-JavaScript]
=====
[source, javascript, indent=0]
----
import { ApolloServer } from "@apollo/server";
Expand Down Expand Up @@ -97,6 +101,7 @@ const { url } = await startStandaloneServer(server, {

console.log(`🚀 Server ready at: ${url}`);
----
=====
====

== User switching
Expand All @@ -105,9 +110,11 @@ User switching completely switches the user authenticating with the database for

An example of configuring user switching on a per request basis can be found in the example below. Note that the username and password are provided in HTTP headers `User` and `Password`, but this would not be recommended for production use:

.TypeScript
[%collapsible]
[.tabbed-example]
====

[.include-with-TypeScript]
=====
[source, typescript, indent=0]
----
import { ApolloServer } from "@apollo/server";
Expand Down Expand Up @@ -148,11 +155,10 @@ const { url } = await startStandaloneServer(server, {

console.log(`🚀 Server ready at: ${url}`);
----
====
=====

.JavaScript
[%collapsible]
====
[.include-with-JavaScript]
=====
[source, javascript, indent=0]
----
import { ApolloServer } from "@apollo/server";
Expand Down Expand Up @@ -193,6 +199,7 @@ const { url } = await startStandaloneServer(server, {

console.log(`🚀 Server ready at: ${url}`);
----
=====
====


Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
= Authentication and Authorization
:description: This section covers authentication andd authorization features in the Neo4j GraphQL Library.
:page-aliases: auth/index.adoc, auth/setup.adoc, auth/authentication.adoc, \
auth/authorization.adoc, auth/auth-directive.adoc, auth/subscriptions.adoc, \
auth/authorization/allow.adoc, auth/authorization/bind.adoc, auth/authorization/roles.adoc, \
auth/authorization/where.adoc, guides/v4-migration/authorization.adoc


[WARNING]
====
===
The `@auth` directive has been replaced by `@authentication` and `@authorization`.
See the xref::migration/v4-migration/authorization.adoc[Migration guide] for details on how to upgrade.
====
===

* xref::authentication-and-authorization/authentication.adoc[Authentication] - Explicit authentication, configured using the `@authentication` directive.
* xref::authentication-and-authorization/authorization.adoc[Authorization] - Authorization rules set using the `@authorization` directive.
Expand Down
79 changes: 43 additions & 36 deletions modules/ROOT/pages/integrations/apollo-federation.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,38 +44,39 @@ const { url } = await startStandaloneServer(server);
console.log(`🚀 Server ready at ${url}`);
----

== Create a new project and install the Apollo Server
== Setup

*Create the project directory*

Create a directory for a new project and `cd` into it:
To proceed with the convertion, follow these steps:

. Create a directory for a new project and `cd` into it:
+
[source, bash]
----
mkdir neo4j-graphql-subgraph-example
cd neo4j-graphql-subgraph-example
----

*Initialize the project*

Initialize a new Node.js project with `npm`:

. Initialize a new Node.js project with `npm`:
+
[source, bash]
----
npm init --yes
npm pkg set type="module"
----
+
[NOTE]
===
This how-to guide sets up the project using ES Modules, which allows the usage of features such as top-level `await`.
===

NOTE: This how-to guide sets up the project using ES Modules, which allows the usage of features such as top-level `await`.

*Language specific setup*

Follow the instructions below to set up with either TypeScript or JavaScript:

.TypeScript
[%collapsible]
. Choose TypeScript or JavaScript to proceed with the setup:
+
[.tabbed-example]
====
. Create a `src` directory with an empty `index.ts` file to contain the entrypoint to your code for this project:

[.include-with-Typescript]
=====
. Create a `src` directory with an empty `index.ts` file to contain the entrypoint to your code:
+
[source, bash]
----
Expand All @@ -90,14 +91,14 @@ touch src/index.ts
npm install --save-dev typescript @types/node @tsconfig/node-lts
----
+
. Create an empty `tsconfig.json` file which will contain the compiler configuration for TypeScript:
. Create an empty `tsconfig.json` file containing the compiler configuration for TypeScript:
+
[source, bash]
----
touch tsconfig.json
----
+
. Add the following configuration to the `tsconfig.json` file created above:
. Add the following configuration to the `tsconfig.json` file:
+
[source, json]
----
Expand All @@ -110,9 +111,13 @@ touch tsconfig.json
}
----
+
NOTE: The configuration above extends the https://github.com/tsconfig/bases#node-lts-tsconfigjson[community base for Node.js LTS], provided by the `@tsconfig/node-lts` package installed above. For more information on the available options, see the https://www.typescriptlang.org/tsconfig[TypeScript Compiler docs].
[NOTE]
===
This configuration extends the https://github.com/tsconfig/bases#node-lts-tsconfigjson[community base for Node.js LTS], provided by the `@tsconfig/node-lts` package installed above.
For more information on the available options, see the https://www.typescriptlang.org/tsconfig[TypeScript Compiler docs].
===
+
. Replace the default `scripts` entry in your `package.json` file with the following `scripts` entry:
. Replace the default `scripts` entry in your `package.json` file with the following:
+
[source, json]
----
Expand All @@ -125,20 +130,19 @@ NOTE: The configuration above extends the https://github.com/tsconfig/bases#node
// other dependencies
}
----
====
=====

.JavaScript
[%collapsible]
====
. Create a `src` directory with an empty `index.js` file to contain the entrypoint to your code for this project:
[.include-with-JavaScript]
=====
. Create a `src` directory with an empty `index.js` file to contain the entrypoint to your code:
+
[source, bash]
----
mkdir src
touch src/index.js
----
+
. Replace the default `scripts` entry in your `package.json` file with the following `scripts` entry:
. Replace the default `scripts` entry in your `package.json` file with the following:
+
[source, json]
----
Expand All @@ -150,18 +154,19 @@ touch src/index.js
// other dependencies
}
----
=====
====

*Install dependencies*

The following dependencies are required for this guide:

+
. This guide requires the installation of the following dependencies:
+
* `@apollo/server`, the library for Apollo Server, is used in this guide to host the subgraph.
* `@neo4j/graphql` is the Neo4j GraphQL Library, which translates GraphQL into Cypher and returns the results.
* `graphql` is the reference implementation of the GraphQL specification. It is required for `@neo4j/graphql` to function.
* `neo4j-driver` is the library for the Neo4j driver, which is required to execute Cypher queries against the database.

Install these dependencies by running the following command:
+

Install them by running this command:

[source, bash]
----
Expand All @@ -184,8 +189,11 @@ const typeDefs = `#graphql
`;
----

Note that this example only includes the Federation `@key` directive.
[NOTE]
===
This example only includes the Federation `@key` directive.
To use more https://www.apollographql.com/docs/federation/federated-types/federated-directives[Federation directives], add them to the `import` array.
===

== Define an entity

Expand All @@ -210,7 +218,7 @@ The Federation gateway expects each key to resolve to one result, so it is good
== Generate a subgraph schema

When using the Neo4j GraphQL Library, generating the subgraph schema can be achieved by calling `getSubgraphSchema` instead of `getSchema`.
In other words, only the following line needs to be changed:
For that, the following line needs to be changed:

[source, javascript]
----
Expand Down Expand Up @@ -257,7 +265,6 @@ const { url } = await startStandaloneServer(server);
console.log(`🚀 Server ready at ${url}`);
----


For further iteration, this subgraph can also be composed into a supergraph.
Check Apollo's guides for more instructions:

Expand Down
Loading