diff --git a/.github/workflows/docs-deploy-surge.yml b/.github/workflows/docs-deploy-surge.yml
index d923c491d..764b0b850 100644
--- a/.github/workflows/docs-deploy-surge.yml
+++ b/.github/workflows/docs-deploy-surge.yml
@@ -57,7 +57,7 @@ jobs:
surge ./site ${{ github.event.repository.owner.login}}-${{ github.event.repository.name}}-${{ steps.get-deploy-id.outputs.deploy-id }}.surge.sh --token ${{ secrets.SURGE_TOKEN }}
- name: Comment on PR
- uses: marocchino/sticky-pull-request-comment@v3
+ uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.get-deploy-id.outputs.deploy-id }}
message: |
diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml
index 6e748719e..0c44b0159 100644
--- a/.github/workflows/docs-pr.yml
+++ b/.github/workflows/docs-pr.yml
@@ -7,8 +7,10 @@ name: "Verify PR"
on:
pull_request:
branches:
- - main
- - dev
+ - "4.4"
+ - "5.0"
+ - "5.x"
+ - "dev"
jobs:
diff --git a/README.adoc b/README.adoc
index 007290bcd..18d012070 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1,6 +1,5 @@
-= Documentation Template
-
-This repo contains the files that you need to start a new Neo4j documentation project.
+= Operations manual
+This repo contains the Neo4j Operations manual source files.
== Prereqs
diff --git a/antora.yml b/antora.yml
index 95a078fe6..0b5cb12e6 100644
--- a/antora.yml
+++ b/antora.yml
@@ -1,7 +1,12 @@
-name: docs-template
-title: Neo4j Documentation template
-version: '1.0'
-# display_version: '1.0-preview'
+name: operations-manual
+title: Operations Manual
+version: '4.4'
start_page: ROOT:index.adoc
nav:
- modules/ROOT/content-nav.adoc
+asciidoc:
+ attributes:
+ neo4j-version: '4.4'
+ neo4j-version-exact: '4.4.9'
+ neo4j-buildnumber: '4.4'
+ neo4j-debian-package-version: 1:4.4.9@
diff --git a/modules/ROOT/content-nav.adoc b/modules/ROOT/content-nav.adoc
index 482f9d4e9..5182c86fa 100644
--- a/modules/ROOT/content-nav.adoc
+++ b/modules/ROOT/content-nav.adoc
@@ -1,3 +1,192 @@
* xref:index.adoc[]
-* xref:getting-started.adoc[]
-* xref:content-types.adoc[]
+* xref:introduction.adoc[]
+* xref:installation/index.adoc[]
+** xref:installation/requirements.adoc[]
+** xref:installation/neo4j-browser.adoc[]
+** xref:installation/neo4j-desktop.adoc[]
+** xref:installation/linux/index.adoc[]
+*** xref:installation/linux/debian.adoc[]
+*** xref:installation/linux/rpm.adoc[]
+*** xref:installation/linux/tarball.adoc[]
+*** xref:installation/linux/systemd.adoc[]
+** xref:installation/osx.adoc[]
+** xref:installation/windows.adoc[]
+
+* xref:cloud-deployments/index.adoc[]
+** xref:cloud-deployments/neo4j-aws.adoc[]
+** xref:cloud-deployments/neo4j-gcp/index.adoc[]
+*** xref:cloud-deployments/neo4j-gcp/single-instance-vm.adoc[]
+*** xref:cloud-deployments/neo4j-gcp/causal-cluster-vm.adoc[]
+*** xref:cloud-deployments/neo4j-gcp/automation-gcp.adoc[]
+** xref:cloud-deployments/neo4j-azure/index.adoc[]
+*** xref:cloud-deployments/neo4j-azure/single-instance-azure.adoc[]
+*** xref:cloud-deployments/neo4j-azure/causal-cluster-azure.adoc[]
+*** xref:cloud-deployments/neo4j-azure/automation-azure.adoc[]
+
+* xref:docker/index.adoc[]
+** xref:docker/introduction.adoc[]
+** xref:docker/configuration.adoc[]
+** xref:docker/clustering.adoc[]
+** xref:docker/operations.adoc[]
+** xref:docker/security.adoc[]
+** xref:docker/maintenance.adoc[]
+** xref:docker/ref-settings.adoc[]
+
+* xref:kubernetes/index.adoc[Kubernetes]
+** xref:kubernetes/introduction.adoc[Introduction]
+** xref:kubernetes/helm-charts-setup.adoc[Configure the Neo4j Helm Chart repository]
+** xref:kubernetes/quickstart-standalone/index.adoc[Quickstart: Deploy a standalone instance]
+*** xref:kubernetes/quickstart-standalone/server-setup.adoc[Neo4j Helm Charts for standalone server deployment]
+*** xref:kubernetes/quickstart-standalone/prerequisites.adoc[Prerequisites]
+*** xref:kubernetes/quickstart-standalone/create-pv.adoc[Create a persistent volume]
+*** xref:kubernetes/quickstart-standalone/create-value-file.adoc[Create a value.yaml file]
+*** xref:kubernetes/quickstart-standalone/install-neo4j.adoc[Install a Neo4j standalone instance]
+*** xref:kubernetes/quickstart-standalone/verify-installation.adoc[Verify the Neo4j installation]
+*** xref:kubernetes/quickstart-standalone/uninstall-cleanup.adoc[Uninstall Neo4j and clean up]
+** xref:kubernetes/quickstart-cluster/index.adoc[Quickstart: Deploy a cluster]
+*** xref:kubernetes/quickstart-cluster/server-setup.adoc[Neo4j Helm Charts for cluster deployments]
+*** xref:kubernetes/quickstart-cluster/prerequisites.adoc[Prerequisites]
+*** xref:kubernetes/quickstart-cluster/create-pv.adoc[Create a persistent volume for each cluster member]
+*** xref:kubernetes/quickstart-cluster/create-value-file.adoc[Create Helm deployment values files]
+*** xref:kubernetes/quickstart-cluster/install-cores.adoc[Install Neo4j core members]
+*** xref:kubernetes/quickstart-cluster/verify-cluster-formation.adoc[Verify the Neo4j cluster formation]
+*** xref:kubernetes/quickstart-cluster/install-read-replicas.adoc[Install Neo4j read replicas]
+*** xref:kubernetes/quickstart-cluster/verify-rr-joined.adoc[Verify the read replica has joined the cluster]
+*** xref:kubernetes/quickstart-cluster/access-inside-k8s.adoc[Access the Neo4j cluster from inside Kubernetes]
+*** xref:kubernetes/quickstart-cluster/access-outside-k8s.adoc[Access the Neo4j cluster from outside Kubernetes]
+*** xref:kubernetes/quickstart-cluster/uninstall-cleanup.adoc[Uninstall Neo4j cluster and clean up]
+** xref:kubernetes/configuration.adoc[Configure a Neo4j Helm deployment]
+** xref:kubernetes/persistent-volumes.adoc[Volume mounts and persistent volumes]
+** xref:kubernetes/accessing-neo4j.adoc[Access a Neo4j standalone server]
+** xref:kubernetes/accessing-cluster.adoc[Access a Neo4j cluster]
+** xref:kubernetes/import-data.adoc[Import data]
+** xref:kubernetes/monitoring.adoc[Monitoring]
+** xref:kubernetes/maintenance.adoc[Operations]
+** Deploy a multi-data center Neo4j cluster
+*** xref:kubernetes/multi-dc-cluster/aks.adoc[Deploy a single Neo4j cluster across multiple AKS clusters]
+** xref:kubernetes/troubleshooting.adoc[Troubleshooting]
+
+* xref:configuration/index.adoc[]
+** xref:configuration/neo4j-conf.adoc[]
+** xref:configuration/file-locations.adoc[]
+//** xref:configuration/network-architecture.adoc[]
+** xref:configuration/ports.adoc[]
+** xref:configuration/connectors.adoc[]
+** xref:configuration/set-initial-password.adoc[]
+** xref:configuration/password-and-user-recovery.adoc[]
+** xref:configuration/dynamic-settings.adoc[]
+** xref:configuration/transaction-logs.adoc[]
+
+* xref:manage-databases/index.adoc[]
+** xref:manage-databases/introduction.adoc[]
+** xref:manage-databases/configuration.adoc[]
+** xref:manage-databases/queries.adoc[]
+** xref:manage-databases/errors.adoc[]
+** xref:manage-databases/causal-cluster.adoc[]
+** xref:manage-databases/remote-alias.adoc[]
+
+* xref:clustering/index.adoc[]
+** xref:clustering/introduction.adoc[]
+** xref:clustering/deploy.adoc[]
+** xref:clustering/seed.adoc[]
+** xref:clustering/discovery.adoc[]
+** xref:clustering/intra-cluster-encryption.adoc[]
+** xref:clustering/internals.adoc[]
+** xref:clustering/settings.adoc[]
+
+* xref:fabric/index.adoc[]
+** xref:fabric/introduction.adoc[]
+** xref:fabric/configuration.adoc[]
+** xref:fabric/queries.adoc[]
+** xref:fabric/considerations.adoc[]
+** xref:fabric/sharding-with-copy.adoc[]
+
+* xref:backup-restore/index.adoc[]
+** xref:backup-restore/planning.adoc[]
+** xref:backup-restore/modes.adoc[]
+** xref:backup-restore/online-backup.adoc[]
+** xref:backup-restore/prepare-restore.adoc[]
+** xref:backup-restore/restore-backup.adoc[]
+** xref:backup-restore/offline-backup.adoc[]
+** xref:backup-restore/restore-dump.adoc[]
+** xref:backup-restore/copy-database.adoc[]
+
+* xref:authentication-authorization/index.adoc[]
+** xref:authentication-authorization/introduction.adoc[]
+** xref:authentication-authorization/built-in-roles.adoc[]
+** xref:authentication-authorization/access-control.adoc[]
+** xref:authentication-authorization/ldap-integration.adoc[]
+** xref:authentication-authorization/sso-integration.adoc[]
+** xref:authentication-authorization/manage-execute-permissions.adoc[]
+** xref:authentication-authorization/terminology.adoc[]
+
+* xref:security/index.adoc[]
+** xref:security/securing-extensions.adoc[]
+** xref:security/ssl-framework.adoc[]
+** xref:security/browser.adoc[]
+** xref:security/checklist.adoc[]
+
+* xref:performance/index.adoc[]
+** xref:performance/memory-configuration.adoc[]
+** xref:performance/index-configuration.adoc[]
+** xref:performance/gc-tuning.adoc[]
+** xref:performance/bolt-thread-pool-configuration.adoc[]
+** xref:performance/linux-file-system-tuning.adoc[]
+** xref:performance/disks-ram-and-other-tips.adoc[]
+** xref:performance/statistics-execution-plans.adoc[]
+** xref:performance/space-reuse.adoc[]
+
+* xref:monitoring/index.adoc[]
+** xref:monitoring/logging.adoc[]
+** xref:monitoring/metrics/index.adoc[]
+*** xref:monitoring/metrics/essential.adoc[]
+*** xref:monitoring/metrics/enable.adoc[]
+*** xref:monitoring/metrics/expose.adoc[]
+*** xref:monitoring/metrics/reference.adoc[]
+** xref:monitoring/query-management.adoc[]
+** xref:monitoring/transaction-management.adoc[]
+** xref:monitoring/connection-management.adoc[]
+** xref:monitoring/background-jobs.adoc[]
+** xref:monitoring/causal-cluster/index.adoc[]
+*** xref:monitoring/causal-cluster/procedures.adoc[]
+*** xref:monitoring/causal-cluster/http-endpoints.adoc[]
+** xref:monitoring/individual-db-states.adoc[]
+
+* xref:tools/index.adoc[]
+** xref:tools/cli-commands.adoc[]
+** xref:tools/neo4j-admin/index.adoc[]
+*** xref:tools/neo4j-admin/consistency-checker.adoc[]
+*** xref:tools/neo4j-admin/neo4j-admin-report.adoc[]
+*** xref:tools/neo4j-admin/neo4j-admin-store-info.adoc[]
+*** xref:tools/neo4j-admin/neo4j-admin-memrec.adoc[]
+*** xref:tools/neo4j-admin/neo4j-admin-import.adoc[]
+*** xref:tools/neo4j-admin/unbind.adoc[]
+*** xref:tools/neo4j-admin/push-to-cloud.adoc[]
+** xref:tools/cypher-shell.adoc[]
+
+* Appendix
+** xref:reference/index.adoc[]
+*** xref:reference/configuration-settings.adoc[]
+*** xref:reference/procedures.adoc[]
+
+** xref:tutorial/index.adoc[]
+*** xref:tutorial/local-causal-cluster.adoc[]
+*** xref:tutorial/causal-backup-restore-db.adoc[]
+*** xref:tutorial/neo4j-admin-import.adoc[]
+*** xref:tutorial/fabric-tutorial.adoc[]
+*** xref:tutorial/tutorial-sso-configuration.adoc[]
+
+** xref:clustering-advanced/index.adoc[]
+*** xref:clustering-advanced/lifecycle.adoc[]
+*** xref:clustering-advanced/multi-data-center/index.adoc[]
+*** xref:clustering-advanced/multi-data-center/design.adoc[]
+*** xref:clustering-advanced/multi-data-center/configuration.adoc[]
+*** xref:clustering-advanced/multi-data-center/load-balancing.adoc[]
+*** xref:clustering-advanced/multi-data-center/disaster-recovery.adoc[]
+** xref:clustering-advanced/embedded.adoc[]
+
+** xref:deprecated-security-procedures/index.adoc[]
+*** xref:deprecated-security-procedures/enterprise-edition.adoc[]
+*** xref:deprecated-security-procedures/community-edition.adoc[]
+
+** xref:routing-decisions.adoc[]
diff --git a/modules/ROOT/examples/example.csv b/modules/ROOT/examples/example.csv
deleted file mode 100644
index 1932aa0d8..000000000
--- a/modules/ROOT/examples/example.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-Field1,Field2
-Value1,Value2
\ No newline at end of file
diff --git a/modules/ROOT/images/2-dc-homogeneous-2-core.svg b/modules/ROOT/images/2-dc-homogeneous-2-core.svg
new file mode 100644
index 000000000..750b476e1
--- /dev/null
+++ b/modules/ROOT/images/2-dc-homogeneous-2-core.svg
@@ -0,0 +1,95 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/3-dc-heterogeneous.svg b/modules/ROOT/images/3-dc-heterogeneous.svg
new file mode 100644
index 000000000..71ab19a2c
--- /dev/null
+++ b/modules/ROOT/images/3-dc-heterogeneous.svg
@@ -0,0 +1,138 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/3-dc-homogeneous-3-core.svg b/modules/ROOT/images/3-dc-homogeneous-3-core.svg
new file mode 100644
index 000000000..ba9fd9613
--- /dev/null
+++ b/modules/ROOT/images/3-dc-homogeneous-3-core.svg
@@ -0,0 +1,220 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/3-dc-homogeneous.svg b/modules/ROOT/images/3-dc-homogeneous.svg
new file mode 100644
index 000000000..0edd7c3ff
--- /dev/null
+++ b/modules/ROOT/images/3-dc-homogeneous.svg
@@ -0,0 +1,158 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/ACL.png b/modules/ROOT/images/ACL.png
new file mode 100644
index 000000000..2902dba1a
Binary files /dev/null and b/modules/ROOT/images/ACL.png differ
diff --git a/modules/ROOT/images/CommunityEdition-example.png b/modules/ROOT/images/CommunityEdition-example.png
new file mode 100644
index 000000000..3506095b8
Binary files /dev/null and b/modules/ROOT/images/CommunityEdition-example.png differ
diff --git a/modules/ROOT/images/Defaultdatabase-example.png b/modules/ROOT/images/Defaultdatabase-example.png
new file mode 100644
index 000000000..40ab2c9f1
Binary files /dev/null and b/modules/ROOT/images/Defaultdatabase-example.png differ
diff --git a/modules/ROOT/images/EnterpriseEdition-example.png b/modules/ROOT/images/EnterpriseEdition-example.png
new file mode 100644
index 000000000..6901bc134
Binary files /dev/null and b/modules/ROOT/images/EnterpriseEdition-example.png differ
diff --git a/modules/ROOT/images/RDBMSvsGraph.svg b/modules/ROOT/images/RDBMSvsGraph.svg
new file mode 100644
index 000000000..933192510
--- /dev/null
+++ b/modules/ROOT/images/RDBMSvsGraph.svg
@@ -0,0 +1,3713 @@
+
+
diff --git a/modules/ROOT/images/RDBMSvsGraph.svg.png b/modules/ROOT/images/RDBMSvsGraph.svg.png
new file mode 100644
index 000000000..cd46fb3ed
Binary files /dev/null and b/modules/ROOT/images/RDBMSvsGraph.svg.png differ
diff --git a/modules/ROOT/images/availability.svg b/modules/ROOT/images/availability.svg
new file mode 100644
index 000000000..22087d5fb
--- /dev/null
+++ b/modules/ROOT/images/availability.svg
@@ -0,0 +1,145 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/aws-acknowledgement.png b/modules/ROOT/images/aws-acknowledgement.png
new file mode 100644
index 000000000..f0b090309
Binary files /dev/null and b/modules/ROOT/images/aws-acknowledgement.png differ
diff --git a/modules/ROOT/images/backup-backup_address.svg b/modules/ROOT/images/backup-backup_address.svg
new file mode 100644
index 000000000..5bc33c9ad
--- /dev/null
+++ b/modules/ROOT/images/backup-backup_address.svg
@@ -0,0 +1,102 @@
+
+
diff --git a/modules/ROOT/images/backup-causal_clustering.transaction.svg b/modules/ROOT/images/backup-causal_clustering.transaction.svg
new file mode 100644
index 000000000..57cf8b73a
--- /dev/null
+++ b/modules/ROOT/images/backup-causal_clustering.transaction.svg
@@ -0,0 +1,99 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/backup-local_server.svg b/modules/ROOT/images/backup-local_server.svg
new file mode 100644
index 000000000..a33bdfb6a
--- /dev/null
+++ b/modules/ROOT/images/backup-local_server.svg
@@ -0,0 +1,72 @@
+
+
diff --git a/modules/ROOT/images/backup-separate-server.svg b/modules/ROOT/images/backup-separate-server.svg
new file mode 100644
index 000000000..cf5a62129
--- /dev/null
+++ b/modules/ROOT/images/backup-separate-server.svg
@@ -0,0 +1,76 @@
+
+
diff --git a/modules/ROOT/images/basic-filtering.png b/modules/ROOT/images/basic-filtering.png
new file mode 100644
index 000000000..a86c2a34d
Binary files /dev/null and b/modules/ROOT/images/basic-filtering.png differ
diff --git a/modules/ROOT/images/batch-request-api.png b/modules/ROOT/images/batch-request-api.png
new file mode 100644
index 000000000..e10ce9645
Binary files /dev/null and b/modules/ROOT/images/batch-request-api.png differ
diff --git a/modules/ROOT/images/cache-sharding-neo.png b/modules/ROOT/images/cache-sharding-neo.png
new file mode 100644
index 000000000..0af7f164e
Binary files /dev/null and b/modules/ROOT/images/cache-sharding-neo.png differ
diff --git a/modules/ROOT/images/causal-clustering-discovery.svg b/modules/ROOT/images/causal-clustering-discovery.svg
new file mode 100644
index 000000000..d6d020ff9
--- /dev/null
+++ b/modules/ROOT/images/causal-clustering-discovery.svg
@@ -0,0 +1,167 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/causal-clustering-drivers.svg b/modules/ROOT/images/causal-clustering-drivers.svg
new file mode 100644
index 000000000..fee3cf355
--- /dev/null
+++ b/modules/ROOT/images/causal-clustering-drivers.svg
@@ -0,0 +1,312 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/causal-clustering.svg b/modules/ROOT/images/causal-clustering.svg
new file mode 100644
index 000000000..b5f151cc6
--- /dev/null
+++ b/modules/ROOT/images/causal-clustering.svg
@@ -0,0 +1,110 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/cluster-architecture.png b/modules/ROOT/images/cluster-architecture.png
new file mode 100644
index 000000000..0d8adb185
Binary files /dev/null and b/modules/ROOT/images/cluster-architecture.png differ
diff --git a/modules/ROOT/images/cluster-failover-neo-logo.png b/modules/ROOT/images/cluster-failover-neo-logo.png
new file mode 100644
index 000000000..7be5d6d24
Binary files /dev/null and b/modules/ROOT/images/cluster-failover-neo-logo.png differ
diff --git a/modules/ROOT/images/cluster-failover-neo-styled.png b/modules/ROOT/images/cluster-failover-neo-styled.png
new file mode 100644
index 000000000..a44807b68
Binary files /dev/null and b/modules/ROOT/images/cluster-failover-neo-styled.png differ
diff --git a/modules/ROOT/images/cluster-on-k8s.png b/modules/ROOT/images/cluster-on-k8s.png
new file mode 100644
index 000000000..5526d750c
Binary files /dev/null and b/modules/ROOT/images/cluster-on-k8s.png differ
diff --git a/modules/ROOT/images/cluster-w-lb-neo-logo.png b/modules/ROOT/images/cluster-w-lb-neo-logo.png
new file mode 100644
index 000000000..fc5b11a2b
Binary files /dev/null and b/modules/ROOT/images/cluster-w-lb-neo-logo.png differ
diff --git a/modules/ROOT/images/cluster-w-lb-neo-styled.png b/modules/ROOT/images/cluster-w-lb-neo-styled.png
new file mode 100644
index 000000000..fda99217e
Binary files /dev/null and b/modules/ROOT/images/cluster-w-lb-neo-styled.png differ
diff --git a/modules/ROOT/images/cluster_1.png b/modules/ROOT/images/cluster_1.png
new file mode 100644
index 000000000..09ce47717
Binary files /dev/null and b/modules/ROOT/images/cluster_1.png differ
diff --git a/modules/ROOT/images/cluster_high_availability.png b/modules/ROOT/images/cluster_high_availability.png
new file mode 100644
index 000000000..6e0154c63
Binary files /dev/null and b/modules/ROOT/images/cluster_high_availability.png differ
diff --git a/modules/ROOT/images/cluster_read_scalability.png b/modules/ROOT/images/cluster_read_scalability.png
new file mode 100644
index 000000000..64d91534c
Binary files /dev/null and b/modules/ROOT/images/cluster_read_scalability.png differ
diff --git a/modules/ROOT/images/create-stack.png b/modules/ROOT/images/create-stack.png
new file mode 100644
index 000000000..0e6611fdf
Binary files /dev/null and b/modules/ROOT/images/create-stack.png differ
diff --git a/modules/ROOT/images/dc-recovery-1.svg b/modules/ROOT/images/dc-recovery-1.svg
new file mode 100644
index 000000000..157e3ec75
--- /dev/null
+++ b/modules/ROOT/images/dc-recovery-1.svg
@@ -0,0 +1,115 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/dc-recovery-2.svg b/modules/ROOT/images/dc-recovery-2.svg
new file mode 100644
index 000000000..6bc85fba0
--- /dev/null
+++ b/modules/ROOT/images/dc-recovery-2.svg
@@ -0,0 +1,116 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/deploy-cluster-initial.svg b/modules/ROOT/images/deploy-cluster-initial.svg
new file mode 100644
index 000000000..95f9dd4e8
--- /dev/null
+++ b/modules/ROOT/images/deploy-cluster-initial.svg
@@ -0,0 +1,462 @@
+
+
diff --git a/modules/ROOT/images/dns-resolution.png b/modules/ROOT/images/dns-resolution.png
new file mode 100644
index 000000000..d17a0aa1d
Binary files /dev/null and b/modules/ROOT/images/dns-resolution.png differ
diff --git a/modules/ROOT/images/examples-matrix.png b/modules/ROOT/images/examples-matrix.png
new file mode 100644
index 000000000..f80fc4532
Binary files /dev/null and b/modules/ROOT/images/examples-matrix.png differ
diff --git a/modules/ROOT/images/fabric-browser/fabric-default.png b/modules/ROOT/images/fabric-browser/fabric-default.png
new file mode 100644
index 000000000..966799800
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/fabric-default.png differ
diff --git a/modules/ROOT/images/fabric-browser/fabric-setup.png b/modules/ROOT/images/fabric-browser/fabric-setup.png
new file mode 100644
index 000000000..5efc5edbc
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/fabric-setup.png differ
diff --git a/modules/ROOT/images/fabric-browser/federation.png b/modules/ROOT/images/fabric-browser/federation.png
new file mode 100644
index 000000000..b85fbc778
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/federation.png differ
diff --git a/modules/ROOT/images/fabric-browser/northwind-datamodel.png b/modules/ROOT/images/fabric-browser/northwind-datamodel.png
new file mode 100644
index 000000000..98fc9b192
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/northwind-datamodel.png differ
diff --git a/modules/ROOT/images/fabric-browser/northwind-fabric-datamodel.png b/modules/ROOT/images/fabric-browser/northwind-fabric-datamodel.png
new file mode 100644
index 000000000..1985c1555
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/northwind-fabric-datamodel.png differ
diff --git a/modules/ROOT/images/fabric-browser/northwind-logo.jpeg b/modules/ROOT/images/fabric-browser/northwind-logo.jpeg
new file mode 100644
index 000000000..1e1361018
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/northwind-logo.jpeg differ
diff --git a/modules/ROOT/images/fabric-browser/sharding.png b/modules/ROOT/images/fabric-browser/sharding.png
new file mode 100644
index 000000000..4468c5261
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/sharding.png differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/data.plist b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/data.plist
new file mode 100644
index 000000000..338f7f7a3
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/data.plist differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/en.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/en.strings
new file mode 100644
index 000000000..202e82ef1
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/en.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/es.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/es.strings
new file mode 100644
index 000000000..c1e8c77ad
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/es.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/fr.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/fr.strings
new file mode 100644
index 000000000..f6082eb75
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/fr.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/image1.png b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/image1.png
new file mode 100644
index 000000000..60dfd1aab
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/image1.png differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/it.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/it.strings
new file mode 100644
index 000000000..267d83c2d
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/it.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ja.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ja.strings
new file mode 100644
index 000000000..372bf754a
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ja.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ko.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ko.strings
new file mode 100644
index 000000000..d3d044dbd
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ko.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/nl.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/nl.strings
new file mode 100644
index 000000000..46a59bdc6
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/nl.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/preview.jpeg b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/preview.jpeg
new file mode 100644
index 000000000..ea2b4a9ad
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/preview.jpeg differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/pt-BR.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/pt-BR.strings
new file mode 100644
index 000000000..aaa3e1a6a
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/pt-BR.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ru.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ru.strings
new file mode 100644
index 000000000..40b508048
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/ru.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/zh-Hans.strings b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/zh-Hans.strings
new file mode 100644
index 000000000..42834befd
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-data-model.graffle/zh-Hans.strings differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/data.plist b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/data.plist
new file mode 100644
index 000000000..a5c04451a
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/data.plist differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image1.png b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image1.png
new file mode 100644
index 000000000..79a32bfc1
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image1.png differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image3.png b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image3.png
new file mode 100644
index 000000000..60dfd1aab
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image3.png differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image5.png b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image5.png
new file mode 100644
index 000000000..78af38635
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/image5.png differ
diff --git a/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/preview.jpeg b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/preview.jpeg
new file mode 100644
index 000000000..1af9d8fd1
Binary files /dev/null and b/modules/ROOT/images/fabric-browser/src/fabric-setup.graffle/preview.jpeg differ
diff --git a/modules/ROOT/images/fabric-deployment-scalable.png b/modules/ROOT/images/fabric-deployment-scalable.png
new file mode 100644
index 000000000..3d1ec08c1
Binary files /dev/null and b/modules/ROOT/images/fabric-deployment-scalable.png differ
diff --git a/modules/ROOT/images/fabric-deployment.png b/modules/ROOT/images/fabric-deployment.png
new file mode 100644
index 000000000..64fe1dd15
Binary files /dev/null and b/modules/ROOT/images/fabric-deployment.png differ
diff --git a/modules/ROOT/images/fabric-minimal-remote-setting.png b/modules/ROOT/images/fabric-minimal-remote-setting.png
new file mode 100644
index 000000000..cc9f9b875
Binary files /dev/null and b/modules/ROOT/images/fabric-minimal-remote-setting.png differ
diff --git a/modules/ROOT/images/fabric-minimal-setting.png b/modules/ROOT/images/fabric-minimal-setting.png
new file mode 100644
index 000000000..fb34645c7
Binary files /dev/null and b/modules/ROOT/images/fabric-minimal-setting.png differ
diff --git a/modules/ROOT/images/fabric-setting.png b/modules/ROOT/images/fabric-setting.png
new file mode 100644
index 000000000..c26d42c13
Binary files /dev/null and b/modules/ROOT/images/fabric-setting.png differ
diff --git a/modules/ROOT/images/fabric-single-instance.png b/modules/ROOT/images/fabric-single-instance.png
new file mode 100644
index 000000000..b1f0856c9
Binary files /dev/null and b/modules/ROOT/images/fabric-single-instance.png differ
diff --git a/modules/ROOT/images/fabric/fabric-default.png b/modules/ROOT/images/fabric/fabric-default.png
new file mode 100644
index 000000000..966799800
Binary files /dev/null and b/modules/ROOT/images/fabric/fabric-default.png differ
diff --git a/modules/ROOT/images/fabric/fabric-setup.png b/modules/ROOT/images/fabric/fabric-setup.png
new file mode 100644
index 000000000..5efc5edbc
Binary files /dev/null and b/modules/ROOT/images/fabric/fabric-setup.png differ
diff --git a/modules/ROOT/images/fabric/federation.png b/modules/ROOT/images/fabric/federation.png
new file mode 100644
index 000000000..b85fbc778
Binary files /dev/null and b/modules/ROOT/images/fabric/federation.png differ
diff --git a/modules/ROOT/images/fabric/northwind-datamodel.png b/modules/ROOT/images/fabric/northwind-datamodel.png
new file mode 100644
index 000000000..98fc9b192
Binary files /dev/null and b/modules/ROOT/images/fabric/northwind-datamodel.png differ
diff --git a/modules/ROOT/images/fabric/northwind-fabric-datamodel.png b/modules/ROOT/images/fabric/northwind-fabric-datamodel.png
new file mode 100644
index 000000000..1985c1555
Binary files /dev/null and b/modules/ROOT/images/fabric/northwind-fabric-datamodel.png differ
diff --git a/modules/ROOT/images/fabric/northwind-logo.jpeg b/modules/ROOT/images/fabric/northwind-logo.jpeg
new file mode 100644
index 000000000..1e1361018
Binary files /dev/null and b/modules/ROOT/images/fabric/northwind-logo.jpeg differ
diff --git a/modules/ROOT/images/fabric/sharding.png b/modules/ROOT/images/fabric/sharding.png
new file mode 100644
index 000000000..4468c5261
Binary files /dev/null and b/modules/ROOT/images/fabric/sharding.png differ
diff --git a/modules/ROOT/images/fabric/sharding2.png b/modules/ROOT/images/fabric/sharding2.png
new file mode 100644
index 000000000..58a4537c2
Binary files /dev/null and b/modules/ROOT/images/fabric/sharding2.png differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/data.plist b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/data.plist
new file mode 100644
index 000000000..338f7f7a3
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/data.plist differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/en.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/en.strings
new file mode 100644
index 000000000..202e82ef1
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/en.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/es.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/es.strings
new file mode 100644
index 000000000..c1e8c77ad
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/es.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/fr.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/fr.strings
new file mode 100644
index 000000000..f6082eb75
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/fr.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/image1.png b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/image1.png
new file mode 100644
index 000000000..60dfd1aab
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/image1.png differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/it.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/it.strings
new file mode 100644
index 000000000..267d83c2d
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/it.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ja.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ja.strings
new file mode 100644
index 000000000..372bf754a
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ja.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ko.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ko.strings
new file mode 100644
index 000000000..d3d044dbd
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ko.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/nl.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/nl.strings
new file mode 100644
index 000000000..46a59bdc6
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/nl.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/preview.jpeg b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/preview.jpeg
new file mode 100644
index 000000000..ea2b4a9ad
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/preview.jpeg differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/pt-BR.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/pt-BR.strings
new file mode 100644
index 000000000..aaa3e1a6a
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/pt-BR.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ru.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ru.strings
new file mode 100644
index 000000000..40b508048
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/ru.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-data-model.graffle/zh-Hans.strings b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/zh-Hans.strings
new file mode 100644
index 000000000..42834befd
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-data-model.graffle/zh-Hans.strings differ
diff --git a/modules/ROOT/images/fabric/src/fabric-setup.graffle/data.plist b/modules/ROOT/images/fabric/src/fabric-setup.graffle/data.plist
new file mode 100644
index 000000000..a5c04451a
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-setup.graffle/data.plist differ
diff --git a/modules/ROOT/images/fabric/src/fabric-setup.graffle/image1.png b/modules/ROOT/images/fabric/src/fabric-setup.graffle/image1.png
new file mode 100644
index 000000000..79a32bfc1
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-setup.graffle/image1.png differ
diff --git a/modules/ROOT/images/fabric/src/fabric-setup.graffle/image3.png b/modules/ROOT/images/fabric/src/fabric-setup.graffle/image3.png
new file mode 100644
index 000000000..60dfd1aab
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-setup.graffle/image3.png differ
diff --git a/modules/ROOT/images/fabric/src/fabric-setup.graffle/image5.png b/modules/ROOT/images/fabric/src/fabric-setup.graffle/image5.png
new file mode 100644
index 000000000..78af38635
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-setup.graffle/image5.png differ
diff --git a/modules/ROOT/images/fabric/src/fabric-setup.graffle/preview.jpeg b/modules/ROOT/images/fabric/src/fabric-setup.graffle/preview.jpeg
new file mode 100644
index 000000000..1af9d8fd1
Binary files /dev/null and b/modules/ROOT/images/fabric/src/fabric-setup.graffle/preview.jpeg differ
diff --git a/modules/ROOT/images/failure-optimistic.png b/modules/ROOT/images/failure-optimistic.png
new file mode 100644
index 000000000..b34e8f167
Binary files /dev/null and b/modules/ROOT/images/failure-optimistic.png differ
diff --git a/modules/ROOT/images/failure-reset.png b/modules/ROOT/images/failure-reset.png
new file mode 100644
index 000000000..1ed5a7cfe
Binary files /dev/null and b/modules/ROOT/images/failure-reset.png differ
diff --git a/modules/ROOT/images/favicon.ico b/modules/ROOT/images/favicon.ico
new file mode 100644
index 000000000..351511a36
Binary files /dev/null and b/modules/ROOT/images/favicon.ico differ
diff --git a/modules/ROOT/images/flat-vs-segmented-network.svg b/modules/ROOT/images/flat-vs-segmented-network.svg
new file mode 100644
index 000000000..b3bb023cb
--- /dev/null
+++ b/modules/ROOT/images/flat-vs-segmented-network.svg
@@ -0,0 +1,189 @@
+
diff --git a/modules/ROOT/images/friends-of-friends.png b/modules/ROOT/images/friends-of-friends.png
new file mode 100644
index 000000000..72ff0264e
Binary files /dev/null and b/modules/ROOT/images/friends-of-friends.png differ
diff --git a/modules/ROOT/images/friends-of-friends2.psd b/modules/ROOT/images/friends-of-friends2.psd
new file mode 100644
index 000000000..2307ae96e
Binary files /dev/null and b/modules/ROOT/images/friends-of-friends2.psd differ
diff --git a/modules/ROOT/images/front-cover.svg b/modules/ROOT/images/front-cover.svg
new file mode 100644
index 000000000..d41e7fd76
--- /dev/null
+++ b/modules/ROOT/images/front-cover.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/graphalgo-astar.png b/modules/ROOT/images/graphalgo-astar.png
new file mode 100644
index 000000000..1a602c5c0
Binary files /dev/null and b/modules/ROOT/images/graphalgo-astar.png differ
diff --git a/modules/ROOT/images/ha-architecture.svg b/modules/ROOT/images/ha-architecture.svg
new file mode 100644
index 000000000..0ddf9ace9
--- /dev/null
+++ b/modules/ROOT/images/ha-architecture.svg
@@ -0,0 +1,103 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/hello-world.png b/modules/ROOT/images/hello-world.png
new file mode 100644
index 000000000..0d7612767
Binary files /dev/null and b/modules/ROOT/images/hello-world.png differ
diff --git a/modules/ROOT/images/hierarchical-read-replicas.svg b/modules/ROOT/images/hierarchical-read-replicas.svg
new file mode 100644
index 000000000..ba2423a57
--- /dev/null
+++ b/modules/ROOT/images/hierarchical-read-replicas.svg
@@ -0,0 +1,355 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/indexing-imdb-example.png b/modules/ROOT/images/indexing-imdb-example.png
new file mode 100644
index 000000000..47afbf728
Binary files /dev/null and b/modules/ROOT/images/indexing-imdb-example.png differ
diff --git a/modules/ROOT/images/logo-neo4j.svg b/modules/ROOT/images/logo-neo4j.svg
new file mode 100644
index 000000000..2eb0a7376
--- /dev/null
+++ b/modules/ROOT/images/logo-neo4j.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/manage-dbs-community.png b/modules/ROOT/images/manage-dbs-community.png
new file mode 100644
index 000000000..f3ff5068e
Binary files /dev/null and b/modules/ROOT/images/manage-dbs-community.png differ
diff --git a/modules/ROOT/images/manage-dbs-default.png b/modules/ROOT/images/manage-dbs-default.png
new file mode 100644
index 000000000..24ddaeae2
Binary files /dev/null and b/modules/ROOT/images/manage-dbs-default.png differ
diff --git a/modules/ROOT/images/manage-dbs-enterprise.png b/modules/ROOT/images/manage-dbs-enterprise.png
new file mode 100644
index 000000000..bb28c1489
Binary files /dev/null and b/modules/ROOT/images/manage-dbs-enterprise.png differ
diff --git a/modules/ROOT/images/many-hop-causal-consistency.svg b/modules/ROOT/images/many-hop-causal-consistency.svg
new file mode 100644
index 000000000..5bcda5de6
--- /dev/null
+++ b/modules/ROOT/images/many-hop-causal-consistency.svg
@@ -0,0 +1,375 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/matrix.png b/modules/ROOT/images/matrix.png
new file mode 100644
index 000000000..3635789b6
Binary files /dev/null and b/modules/ROOT/images/matrix.png differ
diff --git a/modules/ROOT/images/milestone-working-example.png b/modules/ROOT/images/milestone-working-example.png
new file mode 100644
index 000000000..92f529e7d
Binary files /dev/null and b/modules/ROOT/images/milestone-working-example.png differ
diff --git a/modules/ROOT/images/milestone-working-example2.png b/modules/ROOT/images/milestone-working-example2.png
new file mode 100644
index 000000000..a5728be40
Binary files /dev/null and b/modules/ROOT/images/milestone-working-example2.png differ
diff --git a/modules/ROOT/images/milestone-working-example3.png b/modules/ROOT/images/milestone-working-example3.png
new file mode 100644
index 000000000..7705e7f80
Binary files /dev/null and b/modules/ROOT/images/milestone-working-example3.png differ
diff --git a/modules/ROOT/images/milestone-working-example4.png b/modules/ROOT/images/milestone-working-example4.png
new file mode 100644
index 000000000..3da34a723
Binary files /dev/null and b/modules/ROOT/images/milestone-working-example4.png differ
diff --git a/modules/ROOT/images/multi-dc-cc-aks.png b/modules/ROOT/images/multi-dc-cc-aks.png
new file mode 100644
index 000000000..48fad9136
Binary files /dev/null and b/modules/ROOT/images/multi-dc-cc-aks.png differ
diff --git a/modules/ROOT/images/multicluster-example.svg b/modules/ROOT/images/multicluster-example.svg
new file mode 100644
index 000000000..9c225df72
--- /dev/null
+++ b/modules/ROOT/images/multicluster-example.svg
@@ -0,0 +1,153 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/multicluster-high-level-example.svg b/modules/ROOT/images/multicluster-high-level-example.svg
new file mode 100644
index 000000000..1009becc3
--- /dev/null
+++ b/modules/ROOT/images/multicluster-high-level-example.svg
@@ -0,0 +1,96 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/multicluster-monitoring.svg b/modules/ROOT/images/multicluster-monitoring.svg
new file mode 100644
index 000000000..4eefb932f
--- /dev/null
+++ b/modules/ROOT/images/multicluster-monitoring.svg
@@ -0,0 +1,111 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/neo4j-green.png b/modules/ROOT/images/neo4j-green.png
new file mode 100644
index 000000000..95e0a0824
Binary files /dev/null and b/modules/ROOT/images/neo4j-green.png differ
diff --git a/modules/ROOT/images/neo4j-lb.png b/modules/ROOT/images/neo4j-lb.png
new file mode 100644
index 000000000..e97d05eeb
Binary files /dev/null and b/modules/ROOT/images/neo4j-lb.png differ
diff --git a/modules/ROOT/images/neo4j-logo.png b/modules/ROOT/images/neo4j-logo.png
new file mode 100644
index 000000000..afbd019d1
Binary files /dev/null and b/modules/ROOT/images/neo4j-logo.png differ
diff --git a/modules/ROOT/images/neo4j-memory-management.svg b/modules/ROOT/images/neo4j-memory-management.svg
new file mode 100644
index 000000000..05f42cfd5
--- /dev/null
+++ b/modules/ROOT/images/neo4j-memory-management.svg
@@ -0,0 +1,128 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/neo4j-service.png b/modules/ROOT/images/neo4j-service.png
new file mode 100644
index 000000000..17d59000e
Binary files /dev/null and b/modules/ROOT/images/neo4j-service.png differ
diff --git a/modules/ROOT/images/neo4j_logo_globe.png b/modules/ROOT/images/neo4j_logo_globe.png
new file mode 100644
index 000000000..4eaaa263c
Binary files /dev/null and b/modules/ROOT/images/neo4j_logo_globe.png differ
diff --git a/modules/ROOT/images/nesw-regions-and-dcs.svg b/modules/ROOT/images/nesw-regions-and-dcs.svg
new file mode 100644
index 000000000..3a9ab4d12
--- /dev/null
+++ b/modules/ROOT/images/nesw-regions-and-dcs.svg
@@ -0,0 +1,354 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/network-architecture1.png b/modules/ROOT/images/network-architecture1.png
new file mode 100644
index 000000000..7c0cdd7c8
Binary files /dev/null and b/modules/ROOT/images/network-architecture1.png differ
diff --git a/modules/ROOT/images/network-architecture2.png b/modules/ROOT/images/network-architecture2.png
new file mode 100644
index 000000000..9c0aa5378
Binary files /dev/null and b/modules/ROOT/images/network-architecture2.png differ
diff --git a/modules/ROOT/images/packstream-integers.png b/modules/ROOT/images/packstream-integers.png
new file mode 100644
index 000000000..8378b4e47
Binary files /dev/null and b/modules/ROOT/images/packstream-integers.png differ
diff --git a/modules/ROOT/images/packstream-sized.png b/modules/ROOT/images/packstream-sized.png
new file mode 100644
index 000000000..368a7f8f2
Binary files /dev/null and b/modules/ROOT/images/packstream-sized.png differ
diff --git a/modules/ROOT/images/packstream-string.png b/modules/ROOT/images/packstream-string.png
new file mode 100644
index 000000000..293715e70
Binary files /dev/null and b/modules/ROOT/images/packstream-string.png differ
diff --git a/modules/ROOT/images/packstream-tinystring.png b/modules/ROOT/images/packstream-tinystring.png
new file mode 100644
index 000000000..d31e84358
Binary files /dev/null and b/modules/ROOT/images/packstream-tinystring.png differ
diff --git a/modules/ROOT/images/peer-to-peer-read-replicas.svg b/modules/ROOT/images/peer-to-peer-read-replicas.svg
new file mode 100644
index 000000000..4a75fd586
--- /dev/null
+++ b/modules/ROOT/images/peer-to-peer-read-replicas.svg
@@ -0,0 +1,239 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/pipeline-of-strategies.svg b/modules/ROOT/images/pipeline-of-strategies.svg
new file mode 100644
index 000000000..6f0280626
--- /dev/null
+++ b/modules/ROOT/images/pipeline-of-strategies.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/modules/ROOT/images/pipelining.png b/modules/ROOT/images/pipelining.png
new file mode 100644
index 000000000..4ae374699
Binary files /dev/null and b/modules/ROOT/images/pipelining.png differ
diff --git a/modules/ROOT/images/play.png b/modules/ROOT/images/play.png
new file mode 100644
index 000000000..93d52024c
Binary files /dev/null and b/modules/ROOT/images/play.png differ
diff --git a/modules/ROOT/images/read-replica-discovery.svg b/modules/ROOT/images/read-replica-discovery.svg
new file mode 100644
index 000000000..14be242a9
--- /dev/null
+++ b/modules/ROOT/images/read-replica-discovery.svg
@@ -0,0 +1,146 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/read-replica-tx-polling.svg b/modules/ROOT/images/read-replica-tx-polling.svg
new file mode 100644
index 000000000..0c8d84106
--- /dev/null
+++ b/modules/ROOT/images/read-replica-tx-polling.svg
@@ -0,0 +1,179 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/refuse-to-be-leader.svg b/modules/ROOT/images/refuse-to-be-leader.svg
new file mode 100644
index 000000000..21c9044b5
--- /dev/null
+++ b/modules/ROOT/images/refuse-to-be-leader.svg
@@ -0,0 +1,109 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/remote-alias-overview.svg b/modules/ROOT/images/remote-alias-overview.svg
new file mode 100644
index 000000000..6a06a319e
--- /dev/null
+++ b/modules/ROOT/images/remote-alias-overview.svg
@@ -0,0 +1,43 @@
+
diff --git a/modules/ROOT/images/roles.png b/modules/ROOT/images/roles.png
new file mode 100644
index 000000000..e4b87dd7c
Binary files /dev/null and b/modules/ROOT/images/roles.png differ
diff --git a/modules/ROOT/images/routing-decisions.svg b/modules/ROOT/images/routing-decisions.svg
new file mode 100644
index 000000000..eb62ab714
--- /dev/null
+++ b/modules/ROOT/images/routing-decisions.svg
@@ -0,0 +1,12 @@
+
diff --git a/modules/ROOT/images/safety.svg b/modules/ROOT/images/safety.svg
new file mode 100644
index 000000000..c1f3248c7
--- /dev/null
+++ b/modules/ROOT/images/safety.svg
@@ -0,0 +1,185 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/sdnrx-example.png b/modules/ROOT/images/sdnrx-example.png
new file mode 100644
index 000000000..959ebd38a
Binary files /dev/null and b/modules/ROOT/images/sdnrx-example.png differ
diff --git a/modules/ROOT/images/security-example.png b/modules/ROOT/images/security-example.png
new file mode 100644
index 000000000..a457ed58d
Binary files /dev/null and b/modules/ROOT/images/security-example.png differ
diff --git a/modules/ROOT/images/simple-exchange.png b/modules/ROOT/images/simple-exchange.png
new file mode 100644
index 000000000..3a60e1787
Binary files /dev/null and b/modules/ROOT/images/simple-exchange.png differ
diff --git a/modules/ROOT/images/social_status.png b/modules/ROOT/images/social_status.png
new file mode 100644
index 000000000..565d975f7
Binary files /dev/null and b/modules/ROOT/images/social_status.png differ
diff --git a/modules/ROOT/images/socnet-model.png b/modules/ROOT/images/socnet-model.png
new file mode 100644
index 000000000..df59783ae
Binary files /dev/null and b/modules/ROOT/images/socnet-model.png differ
diff --git a/modules/ROOT/images/socnet-model.svg b/modules/ROOT/images/socnet-model.svg
new file mode 100644
index 000000000..adf95288f
--- /dev/null
+++ b/modules/ROOT/images/socnet-model.svg
@@ -0,0 +1,144 @@
+
+
diff --git a/modules/ROOT/images/src/causal-clustering-discovery.graffle/data.plist b/modules/ROOT/images/src/causal-clustering-discovery.graffle/data.plist
new file mode 100644
index 000000000..263c3fcbc
Binary files /dev/null and b/modules/ROOT/images/src/causal-clustering-discovery.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/causal-clustering-discovery.graffle/image1.tiff b/modules/ROOT/images/src/causal-clustering-discovery.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/causal-clustering-discovery.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/causal-clustering-discovery.graffle/image5.tiff b/modules/ROOT/images/src/causal-clustering-discovery.graffle/image5.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/causal-clustering-discovery.graffle/image5.tiff differ
diff --git a/modules/ROOT/images/src/causal-clustering-drivers.graffle/data.plist b/modules/ROOT/images/src/causal-clustering-drivers.graffle/data.plist
new file mode 100644
index 000000000..d809a9956
Binary files /dev/null and b/modules/ROOT/images/src/causal-clustering-drivers.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/causal-clustering-drivers.graffle/image1.tiff b/modules/ROOT/images/src/causal-clustering-drivers.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/causal-clustering-drivers.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/dc-recovery-1.graffle/data.plist b/modules/ROOT/images/src/dc-recovery-1.graffle/data.plist
new file mode 100644
index 000000000..bd11c882f
Binary files /dev/null and b/modules/ROOT/images/src/dc-recovery-1.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/dc-recovery-1.graffle/image1.tiff b/modules/ROOT/images/src/dc-recovery-1.graffle/image1.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/dc-recovery-1.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/dc-recovery-2.graffle/data.plist b/modules/ROOT/images/src/dc-recovery-2.graffle/data.plist
new file mode 100644
index 000000000..531c2e4d3
Binary files /dev/null and b/modules/ROOT/images/src/dc-recovery-2.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/dc-recovery-2.graffle/image1.tiff b/modules/ROOT/images/src/dc-recovery-2.graffle/image1.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/dc-recovery-2.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/multi-dc.pptx b/modules/ROOT/images/src/multi-dc.pptx
new file mode 100644
index 000000000..bd8b8eaf7
Binary files /dev/null and b/modules/ROOT/images/src/multi-dc.pptx differ
diff --git a/modules/ROOT/images/src/neo4j-memory-management.graffle b/modules/ROOT/images/src/neo4j-memory-management.graffle
new file mode 100644
index 000000000..749b21823
Binary files /dev/null and b/modules/ROOT/images/src/neo4j-memory-management.graffle differ
diff --git a/modules/ROOT/images/src/old/core-edge-discovery.graffle/data.plist b/modules/ROOT/images/src/old/core-edge-discovery.graffle/data.plist
new file mode 100644
index 000000000..f41030307
Binary files /dev/null and b/modules/ROOT/images/src/old/core-edge-discovery.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/old/core-edge-discovery.graffle/image1.tiff b/modules/ROOT/images/src/old/core-edge-discovery.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/old/core-edge-discovery.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/old/core-edge-discovery.graffle/image5.tiff b/modules/ROOT/images/src/old/core-edge-discovery.graffle/image5.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/old/core-edge-discovery.graffle/image5.tiff differ
diff --git a/modules/ROOT/images/src/old/core-edge-drivers.graffle/data.plist b/modules/ROOT/images/src/old/core-edge-drivers.graffle/data.plist
new file mode 100644
index 000000000..850a267d2
Binary files /dev/null and b/modules/ROOT/images/src/old/core-edge-drivers.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/old/core-edge-drivers.graffle/image1.tiff b/modules/ROOT/images/src/old/core-edge-drivers.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/old/core-edge-drivers.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/old/edge-discovery.graffle/data.plist b/modules/ROOT/images/src/old/edge-discovery.graffle/data.plist
new file mode 100644
index 000000000..a8938803c
Binary files /dev/null and b/modules/ROOT/images/src/old/edge-discovery.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/old/edge-discovery.graffle/image1.tiff b/modules/ROOT/images/src/old/edge-discovery.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/old/edge-discovery.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/old/edge-discovery.graffle/image5.tiff b/modules/ROOT/images/src/old/edge-discovery.graffle/image5.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/old/edge-discovery.graffle/image5.tiff differ
diff --git a/modules/ROOT/images/src/old/edge-tx-polling.graffle/data.plist b/modules/ROOT/images/src/old/edge-tx-polling.graffle/data.plist
new file mode 100644
index 000000000..b3bfe9e46
Binary files /dev/null and b/modules/ROOT/images/src/old/edge-tx-polling.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/old/edge-tx-polling.graffle/image1.tiff b/modules/ROOT/images/src/old/edge-tx-polling.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/old/edge-tx-polling.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/old/edge-tx-polling.graffle/image5.tiff b/modules/ROOT/images/src/old/edge-tx-polling.graffle/image5.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/old/edge-tx-polling.graffle/image5.tiff differ
diff --git a/modules/ROOT/images/src/peer-to-peer-read-replicas.graffle/data.plist b/modules/ROOT/images/src/peer-to-peer-read-replicas.graffle/data.plist
new file mode 100644
index 000000000..7c189a795
Binary files /dev/null and b/modules/ROOT/images/src/peer-to-peer-read-replicas.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/peer-to-peer-read-replicas.graffle/image1.png b/modules/ROOT/images/src/peer-to-peer-read-replicas.graffle/image1.png
new file mode 100644
index 000000000..36b8c2a4e
Binary files /dev/null and b/modules/ROOT/images/src/peer-to-peer-read-replicas.graffle/image1.png differ
diff --git a/modules/ROOT/images/src/read-replica-discovery.graffle/data.plist b/modules/ROOT/images/src/read-replica-discovery.graffle/data.plist
new file mode 100644
index 000000000..bbe967b56
Binary files /dev/null and b/modules/ROOT/images/src/read-replica-discovery.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/read-replica-discovery.graffle/image1.tiff b/modules/ROOT/images/src/read-replica-discovery.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/read-replica-discovery.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/read-replica-discovery.graffle/image5.tiff b/modules/ROOT/images/src/read-replica-discovery.graffle/image5.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/read-replica-discovery.graffle/image5.tiff differ
diff --git a/modules/ROOT/images/src/read-replica-tx-polling.graffle/data.plist b/modules/ROOT/images/src/read-replica-tx-polling.graffle/data.plist
new file mode 100644
index 000000000..425c7e221
Binary files /dev/null and b/modules/ROOT/images/src/read-replica-tx-polling.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/read-replica-tx-polling.graffle/image1.tiff b/modules/ROOT/images/src/read-replica-tx-polling.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/read-replica-tx-polling.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/src/read-replica-tx-polling.graffle/image5.tiff b/modules/ROOT/images/src/read-replica-tx-polling.graffle/image5.tiff
new file mode 100644
index 000000000..10cc280f6
Binary files /dev/null and b/modules/ROOT/images/src/read-replica-tx-polling.graffle/image5.tiff differ
diff --git a/modules/ROOT/images/src/refuse-to-be-leader.graffle/data.plist b/modules/ROOT/images/src/refuse-to-be-leader.graffle/data.plist
new file mode 100644
index 000000000..b8caa4b49
Binary files /dev/null and b/modules/ROOT/images/src/refuse-to-be-leader.graffle/data.plist differ
diff --git a/modules/ROOT/images/src/refuse-to-be-leader.graffle/image1.tiff b/modules/ROOT/images/src/refuse-to-be-leader.graffle/image1.tiff
new file mode 100644
index 000000000..9575b27ce
Binary files /dev/null and b/modules/ROOT/images/src/refuse-to-be-leader.graffle/image1.tiff differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-access-token-error.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-access-token-error.png
new file mode 100644
index 000000000..bbfc045ac
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-access-token-error.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-app-roles.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-app-roles.png
new file mode 100644
index 000000000..a3fdd8ec6
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-app-roles.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-client-config.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-client-config.png
new file mode 100644
index 000000000..97a4c945c
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-client-config.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-client-creation.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-client-creation.png
new file mode 100644
index 000000000..477825e23
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-client-creation.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-server-claims.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-server-claims.png
new file mode 100644
index 000000000..fc449d582
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-server-claims.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-server-groups.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-server-groups.png
new file mode 100644
index 000000000..531216cfa
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-server-groups.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-successful-login.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-successful-login.png
new file mode 100644
index 000000000..ae2fc8fb1
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-azure-successful-login.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-cors-error-solution.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-cors-error-solution.png
new file mode 100644
index 000000000..ded412eaa
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-cors-error-solution.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-cors-error.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-cors-error.png
new file mode 100644
index 000000000..0c38d4ee2
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-cors-error.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-google-client-config.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-google-client-config.png
new file mode 100644
index 000000000..8865c96b7
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-google-client-config.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-google-client-creation.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-google-client-creation.png
new file mode 100644
index 000000000..e114c6c3b
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-google-client-creation.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-google-successful-login.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-google-successful-login.png
new file mode 100644
index 000000000..90eb3c294
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-google-successful-login.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-authz-server.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-authz-server.png
new file mode 100644
index 000000000..327cb8341
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-authz-server.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-config-a.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-config-a.png
new file mode 100644
index 000000000..40c241934
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-config-a.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-config-b.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-config-b.png
new file mode 100644
index 000000000..df97dfb03
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-config-b.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-creation.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-creation.png
new file mode 100644
index 000000000..faa08210e
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-client-creation.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-server-claims.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-server-claims.png
new file mode 100644
index 000000000..f2035e54b
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-server-claims.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-server-groups.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-server-groups.png
new file mode 100644
index 000000000..62f9cecf7
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-server-groups.png differ
diff --git a/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-successful-login.png b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-successful-login.png
new file mode 100644
index 000000000..90772dd05
Binary files /dev/null and b/modules/ROOT/images/sso-configuration-tutorials/oidc-okta-successful-login.png differ
diff --git a/modules/ROOT/images/stack-creation.png b/modules/ROOT/images/stack-creation.png
new file mode 100644
index 000000000..481706d2d
Binary files /dev/null and b/modules/ROOT/images/stack-creation.png differ
diff --git a/modules/ROOT/images/stack-details.png b/modules/ROOT/images/stack-details.png
new file mode 100644
index 000000000..9a6aa5758
Binary files /dev/null and b/modules/ROOT/images/stack-details.png differ
diff --git a/modules/ROOT/images/standalone-on-k8s.png b/modules/ROOT/images/standalone-on-k8s.png
new file mode 100644
index 000000000..e3e3a3c1f
Binary files /dev/null and b/modules/ROOT/images/standalone-on-k8s.png differ
diff --git a/modules/ROOT/images/throughput.svg b/modules/ROOT/images/throughput.svg
new file mode 100644
index 000000000..2b8785252
--- /dev/null
+++ b/modules/ROOT/images/throughput.svg
@@ -0,0 +1,123 @@
+
+
\ No newline at end of file
diff --git a/modules/ROOT/images/typical-interaction.png b/modules/ROOT/images/typical-interaction.png
new file mode 100644
index 000000000..b820a18c4
Binary files /dev/null and b/modules/ROOT/images/typical-interaction.png differ
diff --git a/modules/ROOT/pages/authentication-authorization/access-control.adoc b/modules/ROOT/pages/authentication-authorization/access-control.adoc
new file mode 100644
index 000000000..b934c95a5
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/access-control.adoc
@@ -0,0 +1,1149 @@
+[role=enterprise-edition]
+[[auth-access-control]]
+= Fine-grained access control
+:description: Describes an example that illustrates various aspects of security and fine-grained access control.
+
+
+[[auth-access-control-the-data-model]]
+== The data model
+
+Consider a _healthcare_ database, as could be relevant in a medical clinic or hospital.
+A simple version of this might contain only three labels, representing three entity types:
+
+[.compact]
+`(:Patient)`::
+Nodes of this type represent patients that visit the clinic because they have some symptoms.
+Information specific to the patient can be captured in properties:
++
+* `name`
+* `ssn`
+* `address`
+* `dateOfBirth`
+
+`(:Symptom)`::
+A medical database contains a catalog of known illnesses and associated symptoms, which can be described using properties:
++
+* `name`
+* `description`
+
+`(:Disease)`::
+A medical database contains a catalog of known illnesses and associated symptoms, which can be described using properties:
++
+* `name`
+* `description`
+
+These entities will be modelled as nodes, and connected using relationships of the following types:
+
+[.compact]
+`(:Patient)-[:HAS]->(:Symptom)`::
+When a patient reports to the clinic, they will describe their symptoms to the nurse or the doctor.
+The nurse or doctor will then enter this information into the database in the form of connections between the patient node and a graph of known symptoms.
+Possible properties of interest on this relationship could be:
++
+* `date` - date when symptom was reported
+
+`(:Symptom)-[:OF]->(:Disease)`::
+The graph of known symptoms is part of a graph of diseases and their symptoms.
+The relationship between a symptom and a disease can include a probability factor for how likely or common it is for people with that disease to express that symptom.
+This will make it easier for the doctor to make a diagnosis using statistical queries.
++
+* `probability` - probability of symptom matching disease
+
+`(:Patient)-[:DIAGNOSIS]->(:Disease)`::
+The doctor can use the graph of diseases and their symptoms to perform an initial investigation into the most likely diseases to match the patient.
+Based on this, and their own assessment of the patient, they may make a diagnosis which they would persist to the graph through the addition of this relationship with appropriate properties:
++
+* `by`: doctor's name
+* `date`: date of diagnosis
+* `description`: additional doctors' notes
+
+image::security-example.png[title="Healthcare use case", role="middle"]
+
+
+The database would be used by a number of different user types, with different needs for access.
+
+* *Doctors* who need to perform diagnosis on patients.
+* *Nurses* who need to treat patients.
+* *Receptionists* who need to identify and record patient information.
+* *Researchers* who need to perform statistical analysis of medical data.
+* *IT administrators* who need to administer the database, creating and assigning users.
+
+
+[[auth-access-control-security]]
+== Security
+
+When building an application for a specific domain, it is common to model the different users within the application itself.
+However, when working with a database that provides rich user management with roles and privileges,
+it is possible to model these entirely within the database security model (for more information, see link:/docs/cypher-manual/4.4/access-control[Cypher Manual -> Access control]).
+This results in separation of concerns for the access control to the data and the data itself.
+We will show two approaches to using Neo4j security features to support the _healthcare_ database application.
+First, a simple approach using built-in roles, and then a more advanced approach using fine-grained privileges for sub-graph access control.
+
+Our _healthcare_ example involves five users of the database:
+
+* Alice the doctor
+* Daniel the nurse
+* Bob the receptionist
+* Charlie the researcher
+* Tina the IT administrator
+
+These users can be created using the `CREATE USER` command (from the `system` database):
+
+.Creating users
+====
+
+[source, cypher]
+----
+CREATE USER charlie SET PASSWORD $secret1 CHANGE NOT REQUIRED;
+CREATE USER alice SET PASSWORD $secret2 CHANGE NOT REQUIRED;
+CREATE USER daniel SET PASSWORD $secret3 CHANGE NOT REQUIRED;
+CREATE USER bob SET PASSWORD $secret4 CHANGE NOT REQUIRED;
+CREATE USER tina SET PASSWORD $secret5 CHANGE NOT REQUIRED;
+----
+
+====
+
+
+At this point the users have no ability to interact with the database, so we need to grant those capabilities using roles.
+There are two different ways of doing this, either by using the built-in roles, or through more fine-grained access control using privileges and custom roles.
+
+
+[[auth-access-control-using-built-in-roles]]
+== Access control using built-in roles
+
+Neo4j comes with a number of built-in roles that cover a number of common needs:
+
+* `PUBLIC` - All users have this role, can by default access the home database and run all procedures and user-defined functions.
+* `reader` - Can read data from all databases.
+* `editor` - Can read and update all databases, but not expand the schema with new labels, relationship types or property names.
+* `publisher` - Can read and edit, as well as add new labels, relationship types and property names.
+* `architect` - Has all the capabilities of the publisher as well as the ability to manage indexes and constraints.
+* `admin` - Can perform architect actions as well as manage databases, users, roles and privileges.
+
+
+Charlie is a researcher and will not need write access to the database, and so he is assigned the `reader` role.
+Alice the doctor, Daniel the nurse and Bob the receptionist all need to update the database with new patient information, but do not need to expand the schema with new labels, relationship types, property names or indexes.
+We assign them all the `editor` role.
+Tina is the IT administrator that installs and manages the database.
+In order to create all other users, Tina is assigned the `admin` role.
+
+.Granting roles
+====
+
+[source, cypher]
+----
+GRANT ROLE reader TO charlie;
+GRANT ROLE editor TO alice;
+GRANT ROLE editor TO daniel;
+GRANT ROLE editor TO bob;
+GRANT ROLE admin TO tina;
+----
+
+====
+
+A limitation of this approach is that it does allow all users to see all data in the database, and in many real-world scenarios it would be preferable to restrict the users’ access.
+In this example, we would want to restrict the researcher from being able to read any of the patients' personal information, and the receptionist should only be able to see the patient records and nothing more.
+
+These, and more restrictions, could be coded into the application layer.
+However, it is possible and more secure to enforce these kinds of fine-grained restrictions directly within the Neo4j security model, by creating custom roles and assigning specific privileges to those roles.
+
+Since we will be creating new custom roles, the first thing to do is revoke the current roles from the users:
+
+.Revoking roles
+====
+
+[source, cypher]
+----
+REVOKE ROLE reader FROM charlie;
+REVOKE ROLE editor FROM alice;
+REVOKE ROLE editor FROM daniel;
+REVOKE ROLE editor FROM bob;
+REVOKE ROLE admin FROM tina;
+----
+====
+
+Now the users are once again unable to do anything, and so we need to start over by building the set of new privileges based on a complete understanding of what we want each user to be able to do.
+
+
+[[auth-access-control-using-privileges]]
+== Sub-graph access control using privileges
+
+With the concept of _privileges_, we can take much more control over what each user is capable of doing.
+We start by identifying each type of user:
+
+[.compact]
+Doctor::
+Should be able to read and write most of the graph.
+We would, however, like to prevent the doctor from reading the patient’s address.
+We would also like to make sure the doctor can save _diagnoses_ to the database, but not expand the schema of the database with new concepts.
+Receptionist::
+Should be able to read and write all patient data, but not be able to see the symptoms, diseases or diagnoses.
+Researcher::
+Should be able to perform statistical analysis on all data, except patients’ personal information, and as such should not be able to read most patient properties.
+To illustrate two different ways of setting up the same effective privileges, we will create two roles and compare them.
+Nurse::
+The nurse should be able to perform all tasks that both the doctor and the receptionist can do.
+At first one might be tempted to simply grant both those roles, but this does not work as expected.
+We will demonstrate why below, and instead create a dedicated `nurse` role.
+Junior nurse::
+The senior nurse above is able to save diagnoses just as a doctor can.
+However, we might wish to have nurses that are not allowed to make that update to the graph.
+While we could build another role from scratch, this could more easily be achieved by combining the `nurse` role with a new `disableDiagnoses` role that specifically restricts that activity.
+IT administrator::
+This role is very similar to the built-in `admin` role, except that we wish to restrict access to the patients `SSN`,
+as well as prevent the administrator from performing the very critical action of saving a diagnosis, something specific to medical professionals.
+To achieve this, we can create this role by copying the built-in `admin` role and modifying the privileges of that copy.
+User manager::
+It is possible that we would like the IT administrator to be less powerful than described above.
+We can create a new role from scratch, granting only the specific administrative capabilities we actually desire.
+
+// .Creating custom roles
+// ====
+// [source, cypher]
+// ----
+// CREATE ROLE doctor;
+// CREATE ROLE receptionist;
+// CREATE ROLE nurse;
+// CREATE ROLE researcherB;
+// CREATE ROLE researcherW;
+// CREATE ROLE disableDiagnoses;
+// CREATE ROLE itadmin AS COPY OF admin;
+// CREATE ROLE userManager;
+// ----
+// ====
+
+Before we create the new roles and assign them to Alice, Bob, Daniel, Charlie and Tina, we should define the privileges of each role.
+Since all users need `ACCESS` privilege to the `healthcare` database, we can add this to the `PUBLIC` role instead of all the individual roles:
+
+====
+[source, cypher]
+----
+GRANT ACCESS ON DATABASE healthcare TO PUBLIC;
+----
+====
+
+=== Privileges of `itadmin`
+
+This role can be created as a copy of the built-in `admin` role:
+
+====
+[source, cypher, role=systemcmd]
+----
+CREATE ROLE itadmin AS COPY OF admin;
+----
+====
+
+Then all we need to do is deny the two specific actions this role is not supposed to do:
+
+* Should not be able to read any patients social security number.
+* Should not be able to perform medical diagnosis.
+
+====
+[source, cypher, role=systemcmd]
+----
+DENY READ {ssn} ON GRAPH healthcare NODES Patient TO itadmin;
+DENY CREATE ON GRAPH healthcare RELATIONSHIPS DIAGNOSIS TO itadmin;
+----
+====
+
+The complete set of privileges available to users assigned the `itadmin` role can be viewed using the following command:
+
+====
+[source, cypher, role=systemcmd]
+----
+SHOW ROLE itadmin PRIVILEGES AS COMMANDS;
+----
+----
++-------------------------------------------------------------------------+
+| command |
++-------------------------------------------------------------------------+
+| "GRANT ACCESS ON DATABASE * TO `itadmin`" |
+| "GRANT MATCH {*} ON GRAPH * NODE * TO `itadmin`" |
+| "GRANT MATCH {*} ON GRAPH * RELATIONSHIP * TO `itadmin`" |
+| "GRANT WRITE ON GRAPH * TO `itadmin`" |
+| "GRANT INDEX MANAGEMENT ON DATABASE * TO `itadmin`" |
+| "GRANT CONSTRAINT MANAGEMENT ON DATABASE * TO `itadmin`" |
+| "GRANT NAME MANAGEMENT ON DATABASE * TO `itadmin`" |
+| "GRANT START ON DATABASE * TO `itadmin`" |
+| "GRANT STOP ON DATABASE * TO `itadmin`" |
+| "GRANT TRANSACTION MANAGEMENT (*) ON DATABASE * TO `itadmin`" |
+| "GRANT ALL DBMS PRIVILEGES ON DBMS TO `itadmin`" |
+| "DENY READ {ssn} ON GRAPH `healthcare` NODE Patient TO `itadmin`" |
+| "DENY CREATE ON GRAPH `healthcare` RELATIONSHIP DIAGNOSIS TO `itadmin`" |
++-------------------------------------------------------------------------+
+----
+====
+
+[NOTE]
+Privileges that were granted or denied earlier can be revoked using the `REVOKE` command.
+See link:/docs/cypher-manual/4.4/access-control/manage-privileges#access-control-revoke-privileges[the Cypher Manual -> The `REVOKE` command].
+
+In order for the IT administrator `tina` to be provided these privileges, she must be assigned the new role `itadmin`.
+
+====
+[source, cypher, role=systemcmd]
+----
+neo4j@system> GRANT ROLE itadmin TO tina;
+----
+====
+
+To demonstrate that Tina is not able to see the patients `SSN`, we can login to `healthcare` as `tina` and run the query:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.dateOfBirth < date('1972-06-12')
+RETURN n.name, n.ssn, n.address, n.dateOfBirth;
+----
+
+----
++--------------------------------------------------------------------+
+| n.name | n.ssn | n.address | n.dateOfBirth |
++--------------------------------------------------------------------+
+| "Mary Stone" | NULL | "1 secret way, downtown" | 1970-01-15 |
+| "Ally Anderson" | NULL | "1 secret way, downtown" | 1970-08-20 |
+| "Sally Stone" | NULL | "1 secret way, downtown" | 1970-03-12 |
+| "Jane Stone" | NULL | "1 secret way, downtown" | 1970-07-21 |
+| "Ally Svensson" | NULL | "1 secret way, downtown" | 1971-08-15 |
+| "Jane Svensson" | NULL | "1 secret way, downtown" | 1972-05-12 |
+| "Ally Svensson" | NULL | "1 secret way, downtown" | 1971-07-30 |
++--------------------------------------------------------------------+
+----
+
+The results make it seem as if these nodes do not even have an `ssn` field.
+This is a key feature of the security model,
+that users cannot tell the difference between data that is not there,
+and data that is hidden using fine-grained read privileges.
+
+Now remember that we also denied the administrator from saving diagnoses, because that is a critical medical function reserved for only doctors and senior medical staff. We can test this by trying to create `DIAGNOSIS` relationships:
+
+[source, cypher]
+----
+MATCH (n:Patient), (d:Disease)
+CREATE (n)-[:DIAGNOSIS]->(d);
+----
+
+[role=erroronlyqueryresult]
+----
+Create relationship with type 'DIAGNOSIS' is not allowed for user 'tina' with roles [PUBLIC, itadmin].
+----
+
+[NOTE]
+While restrictions on reading data do not result in errors and only make it appear as if the data is not there,
+restrictions on updating, i.e. writing to the graph will produce an appropriate error when the user attempts to perform an update they are not permitted to do.
+
+=== Privileges of `researcher`
+
+Charlie the researcher was previously our only read-only user.
+We could do something similar to what we did with the `itadmin` role, by copying and modifying the `reader` role.
+However, we would like to explicitly illustrate how to build a role from scratch.
+There are various possibilities for building this role using the concepts of either granting or denying a list of privileges:
+
+* *Denying privileges*:
++
+We could grant the role the ability to find all nodes and read all properties (much like the `reader` role) and then deny read access to the `Patient` properties we want to restrict the researcher from seeing, such as `name`, `SSN` and `address`.
+This approach is simple but suffers from one problem.
+If `Patient` nodes are assigned additional properties, _after_ we have restricted access, these new properties will automatically be visible to the researcher, which may not be desirable.
++
+.Denying specific privileges
+====
+
+[source, cypher, role=systemdb]
+----
+// First create the role
+CREATE ROLE researcherB;
+// Then grant access to everything
+GRANT MATCH {*}
+ ON GRAPH healthcare
+ TO researcherB;
+// And deny read on specific node properties
+DENY READ {name, address, ssn}
+ ON GRAPH healthcare
+ NODES Patient
+ TO researcherB;
+// And finally deny traversal of the doctors diagnosis
+DENY TRAVERSE
+ ON GRAPH healthcare
+ RELATIONSHIPS DIAGNOSIS
+ TO researcherB;
+----
+====
+
+* *Granting privileges*:
++
+An alternative is to only provide specific access to the properties we wish the researcher to see.
+Then, the addition of new properties will not automatically make them visible to the researcher.
+In this case, adding new properties to a `Patient` will not mean that the researcher can see them by default.
+If we wish to have them visible, we need to explicitly grant read access.
++
+.Granting specific privileges
+====
+
+[source, cypher]
+----
+// Create the role first
+CREATE ROLE researcherW
+// We allow the researcher to find all nodes
+GRANT TRAVERSE
+ ON GRAPH healthcare
+ NODES *
+ TO researcherW;
+// Now only allow the researcher to traverse specific relationships
+GRANT TRAVERSE
+ ON GRAPH healthcare
+ RELATIONSHIPS HAS, OF
+ TO researcherW;
+// Allow reading of all properties of medical metadata
+GRANT READ {*}
+ ON GRAPH healthcare
+ NODES Symptom, Disease
+ TO researcherW;
+// Allow reading of all properties of the disease-symptom relationship
+GRANT READ {*}
+ ON GRAPH healthcare
+ RELATIONSHIPS OF
+ TO researcherW;
+// Only allow reading dateOfBirth for research purposes
+GRANT READ {dateOfBirth}
+ ON GRAPH healthcare
+ NODES Patient
+ TO researcherW;
+----
+====
+
+In order to test that Charlie now has the privileges we have specified, we assign him to the `researcherB` role (with specifically denied privileges):
+
+====
+[source, cypher, role=systemcmd]
+----
+GRANT ROLE researcherB TO charlie;
+----
+====
+
+We can use a version of the `SHOW PRIVILEGES` command to see Charlies access rights, combining those from `researcherB` and `PUBLIC`:
+
+====
+[source, cypher, role=systemcmd]
+----
+neo4j@system> SHOW USER charlie PRIVILEGES AS COMMANDS;
+----
+----
++-----------------------------------------------------------------------+
+| command |
++-----------------------------------------------------------------------+
+| "GRANT ACCESS ON HOME DATABASE TO $role" |
+| "GRANT ACCESS ON DATABASE `healthcare` TO $role" |
+| "GRANT EXECUTE PROCEDURE * ON DBMS TO $role" |
+| "GRANT EXECUTE FUNCTION * ON DBMS TO $role" |
+| "GRANT MATCH {*} ON GRAPH `healthcare` NODE * TO $role" |
+| "GRANT MATCH {*} ON GRAPH `healthcare` RELATIONSHIP * TO $role" |
+| "DENY TRAVERSE ON GRAPH `healthcare` RELATIONSHIP DIAGNOSIS TO $role" |
+| "DENY READ {address} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "DENY READ {name} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "DENY READ {ssn} ON GRAPH `healthcare` NODE Patient TO $role" |
++-----------------------------------------------------------------------+
+----
+====
+
+Now when Charlie logs into the `healthcare` database and tries to run a command similar to the one used by the `itadmin` above, we will see different results:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.dateOfBirth < date('1972-06-12')
+RETURN n.name, n.ssn, n.address, n.dateOfBirth;
+----
+
+----
++--------------------------------------------+
+| n.name | n.ssn | n.address | n.dateOfBirth |
++--------------------------------------------+
+| NULL | NULL | NULL | 1971-05-31 |
+| NULL | NULL | NULL | 1971-04-17 |
+| NULL | NULL | NULL | 1971-12-27 |
+| NULL | NULL | NULL | 1970-02-13 |
+| NULL | NULL | NULL | 1971-02-04 |
+| NULL | NULL | NULL | 1971-05-10 |
+| NULL | NULL | NULL | 1971-02-21 |
++--------------------------------------------+
+----
+
+Only the date of birth is available, so Charlie the researcher may perform statistical analysis, for example.
+Another query Charlie could try is to find the ten diseases a patient younger than 25 is most likely to be diagnosed with, listed by probability:
+
+[source, cypher]
+----
+WITH datetime() - duration({years:25}) AS timeLimit
+MATCH (n:Patient)
+WHERE n.dateOfBirth > date(timeLimit)
+MATCH (n)-[h:HAS]->(s:Symptom)-[o:OF]->(d:Disease)
+WITH d.name AS disease, o.probability AS prob
+RETURN disease, sum(prob) AS score ORDER BY score DESC LIMIT 10;
+----
+
+----
++-------------------------------------------+
+| disease | score |
++-------------------------------------------+
+| "Acute Argitis" | 95.05395287286318 |
+| "Chronic Someitis" | 88.7220337139605 |
+| "Chronic Placeboitis" | 88.43609533058974 |
+| "Acute Whatitis" | 83.23493746472457 |
+| "Acute Otheritis" | 82.46129768949129 |
+| "Chronic Otheritis" | 82.03650063794025 |
+| "Acute Placeboitis" | 77.34207326583929 |
+| "Acute Yellowitis" | 76.34519967465832 |
+| "Chronic Whatitis" | 73.73968070128234 |
+| "Chronic Yellowitis" | 71.58791287376775 |
++-------------------------------------------+
+----
+
+Now if we revoke the `researcherB` and instead grant the `researcherW` role to Charlie, and re-run these queries, we will see the same results.
+
+[NOTE]
+Privileges that were granted or denied earlier can be revoked using the `REVOKE` command.
+See link:/docs/cypher-manual/4.4/access-control/manage-privileges#access-control-revoke-privileges[the Cypher Manual -> The `REVOKE` command].
+
+=== Privileges of `doctor`
+
+Doctors should be given the ability to read and write almost everything.
+We would, however, like to remove the ability to read the patients' `address` property.
+This role can be built from scratch by assigning full read and write access, and then specifically denying access to the `address` property:
+
+====
+[source, cypher]
+----
+CREATE ROLE doctor;
+GRANT TRAVERSE ON GRAPH healthcare TO doctor;
+GRANT READ {*} ON GRAPH healthcare TO doctor;
+GRANT WRITE ON GRAPH healthcare TO doctor;
+DENY READ {address} ON GRAPH healthcare NODES Patient TO doctor;
+DENY SET PROPERTY {address} ON GRAPH healthcare NODES Patient TO doctor;
+----
+====
+
+To allow Alice to have these privileges, we grant her this new role:
+
+====
+[source, cypher]
+----
+neo4j@system> GRANT ROLE doctor TO alice;
+----
+====
+
+To demonstrate that Alice is not able to see patient addresses, we log in as `alice` to `healthcare` and run the query:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.dateOfBirth < date('1972-06-12')
+RETURN n.name, n.ssn, n.address, n.dateOfBirth;
+----
+
+----
++-------------------------------------------------------+
+| n.name | n.ssn | n.address | n.dateOfBirth |
++-------------------------------------------------------+
+| "Jack Anderson" | 1234647 | NULL | 1970-07-23 |
+| "Joe Svensson" | 1234659 | NULL | 1972-06-07 |
+| "Mary Jackson" | 1234568 | NULL | 1971-10-19 |
+| "Jack Jackson" | 1234583 | NULL | 1971-05-04 |
+| "Ally Smith" | 1234590 | NULL | 1971-12-07 |
+| "Ally Stone" | 1234606 | NULL | 1970-03-29 |
+| "Mark Smith" | 1234610 | NULL | 1971-03-30 |
++-------------------------------------------------------+
+----
+
+As we can see, the doctor has the expected privileges, including being able to see the SSN, but not the address of each patient.
+
+The doctor is also able to see all other node types:
+
+[source, cypher]
+----
+MATCH (n) WITH labels(n) AS labels
+RETURN labels, count(*);
+----
+
+----
++------------------------+
+| labels | count(*) |
++------------------------+
+| ["Patient"] | 101 |
+| ["Symptom"] | 10 |
+| ["Disease"] | 12 |
++------------------------+
+----
+
+In addition, the doctor can traverse the graph, finding symptoms and diseases connected to patients:
+
+[source, cypher]
+----
+MATCH (n:Patient)-[:HAS]->(s:Symptom)-[:OF]->(d:Disease)
+ WHERE n.ssn = 1234657
+RETURN n.name, d.name, count(s) AS score ORDER BY score DESC;
+----
+
+The resulting table shows which are the most likely diagnoses based on symptoms.
+The doctor can use this table to facilitate further questioning and testing of the patient in order to decide on the final diagnosis.
+
+----
++--------------------------------------------------+
+| n.name | d.name | score |
++--------------------------------------------------+
+| "Sally Anderson" | "Chronic Otheritis" | 4 |
+| "Sally Anderson" | "Chronic Yellowitis" | 3 |
+| "Sally Anderson" | "Chronic Placeboitis" | 3 |
+| "Sally Anderson" | "Acute Whatitis" | 2 |
+| "Sally Anderson" | "Acute Yellowitis" | 2 |
+| "Sally Anderson" | "Chronic Someitis" | 2 |
+| "Sally Anderson" | "Chronic Argitis" | 2 |
+| "Sally Anderson" | "Chronic Whatitis" | 2 |
+| "Sally Anderson" | "Acute Someitis" | 1 |
+| "Sally Anderson" | "Acute Argitis" | 1 |
+| "Sally Anderson" | "Acute Otheritis" | 1 |
++--------------------------------------------------+
+----
+
+Once the doctor has investigated further, they would be able to decide on the diagnosis and save that result to the database:
+
+[source, cypher]
+----
+WITH datetime({epochmillis:timestamp()}) AS now
+WITH now, date(now) as today
+MATCH (p:Patient)
+ WHERE p.ssn = 1234657
+MATCH (d:Disease)
+ WHERE d.name = "Chronic Placeboitis"
+MERGE (p)-[i:DIAGNOSIS {by: 'Alice'}]->(d)
+ ON CREATE SET i.created_at = now, i.updated_at = now, i.date = today
+ ON MATCH SET i.updated_at = now
+RETURN p.name, d.name, i.by, i.date, duration.between(i.created_at, i.updated_at) AS updated;
+----
+
+This allows this doctor to record their diagnosis as well as take note of previous diagnoses:
+
+----
++----------------------------------------------------------------------------------------+
+| p.name | d.name | i.by | i.date | updated |
++----------------------------------------------------------------------------------------+
+| "Sally Anderson" | "Chronic Placeboitis" | "Alice" | 2020-05-29 | P0M0DT213.076000000S |
++----------------------------------------------------------------------------------------+
+----
+
+[NOTE]
+In order to create the `DIAGNOSIS` relationship for the first time, it is required to have the privilege to create new types.
+This is also true of the property names `doctor`, `created_at` and `updated_at`.
+This can be fixed by either granting the doctor `NAME MANAGEMENT` privileges or by pre-creating the missing types.
+The latter would be more precise and can be achieved by running,
+as an administrator, the procedures `db.createRelationshipType` and `db.createProperty` with appropriate arguments.
+
+=== Privileges of `receptionist`
+
+Receptionists should only be able to manage patient information.
+They are not allowed to find or read any other parts of the graph.
+In addition, they should be able to create and delete patients, but not any other nodes:
+
+====
+[source, cypher, role=systemdb]
+----
+CREATE ROLE receptionist;
+GRANT MATCH {*} ON GRAPH healthcare NODES Patient TO receptionist;
+GRANT CREATE ON GRAPH healthcare NODES Patient TO receptionist;
+GRANT DELETE ON GRAPH healthcare NODES Patient TO receptionist;
+GRANT SET PROPERTY {*} ON GRAPH healthcare NODES Patient TO receptionist;
+----
+====
+
+[NOTE]
+--
+It would have been simpler to grant global `WRITE` privileges.
+However, this would have the unfortunate side effect of allowing the receptionist the ability to create other nodes,
+like new `Symptom` nodes, even though they would subsequently be unable to find or read those same nodes.
+While there are use cases for being able to create data you cannot read, that is not desired for this model.
+--
+
+====
+[source, cypher]
+----
+neo4j@system> GRANT ROLE receptionist TO bob;
+----
+====
+
+With these privileges, if Bob tries to read the entire database, he will still only see the patients:
+
+[source, cypher]
+----
+MATCH (n) WITH labels(n) AS labels
+RETURN labels, count(*);
+----
+
+----
++------------------------+
+| labels | count(*) |
++------------------------+
+| ["Patient"] | 101 |
++------------------------+
+----
+
+However, Bob is able to see all fields of the Patient records:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.dateOfBirth < date('1972-06-12')
+RETURN n.name, n.ssn, n.address, n.dateOfBirth;
+----
+
+----
++----------------------------------------------------------------------+
+| n.name | n.ssn | n.address | n.dateOfBirth |
++----------------------------------------------------------------------+
+| "Mark Stone" | 1234666 | "1 secret way, downtown" | 1970-08-04 |
+| "Sally Jackson" | 1234633 | "1 secret way, downtown" | 1970-10-21 |
+| "Bob Stone" | 1234581 | "1 secret way, downtown" | 1972-02-16 |
+| "Ally Anderson" | 1234582 | "1 secret way, downtown" | 1970-05-13 |
+| "Mark Svensson" | 1234594 | "1 secret way, downtown" | 1970-01-16 |
+| "Bob Anderson" | 1234597 | "1 secret way, downtown" | 1970-09-23 |
+| "Jack Svensson" | 1234599 | "1 secret way, downtown" | 1971-02-13 |
+| "Mark Jackson" | 1234618 | "1 secret way, downtown" | 1970-03-28 |
+| "Jack Jackson" | 1234623 | "1 secret way, downtown" | 1971-04-02 |
++----------------------------------------------------------------------+
+----
+
+[[detach-delete-restricted-user]]
+
+We have granted Bob the receptionist the ability to delete patient nodes.
+This will allow him to delete any new patients he has just created, but will not allow him the ability to delete patients that have already received diagnoses, because those are connected to parts of the graph the receptionist cannot see.
+Let's demonstrate both these scenarios:
+
+[source, cypher]
+----
+CREATE (n:Patient {
+ ssn:87654321,
+ name: 'Another Patient',
+ email: 'another@example.com',
+ address: '1 secret way, downtown',
+ dateOfBirth: date('2001-01-20')
+})
+RETURN n.name, n.dateOfBirth;
+----
+
+----
++-----------------------------------+
+| n.name | n.dateOfBirth |
++-----------------------------------+
+| "Another Patient" | 2001-01-20 |
++-----------------------------------+
+----
+
+The receptionist is able to modify any patient record:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+WHERE n.ssn = 87654321
+SET n.address = '2 streets down, uptown'
+RETURN n.name, n.dateOfBirth, n.address;
+----
+
+----
++--------------------------------------------------------------+
+| n.name | n.dateOfBirth | n.address |
++--------------------------------------------------------------+
+| "Another Patient" | 2001-01-20 | "2 streets down, uptown" |
++--------------------------------------------------------------+
+----
+
+The receptionist is also able to delete this recently created patient because it is not connected to any other records:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.ssn = 87654321
+DETACH DELETE n;
+----
+
+However, if the receptionist attempts to delete a patient that has existing diagnoses, this will fail:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.ssn = 1234610
+DETACH DELETE n;
+----
+
+[role=erroronlyqueryresult]
+----
+org.neo4j.graphdb.ConstraintViolationException: Cannot delete node<42>, because it still has relationships. To delete this node, you must first delete its relationships.
+----
+
+The reason this fails is that Bob can find the `(:Patient)` node, but does not have sufficient traverse rights to find nor delete the outgoing relationships from it.
+Either he needs to ask Tina the `itadmin` for help for this task, or we can add more privileges to the `receptionist` role:
+
+====
+[source, cypher, role=systemcmd]
+----
+GRANT TRAVERSE ON GRAPH healthcare NODES Symptom, Disease TO receptionist;
+GRANT TRAVERSE ON GRAPH healthcare RELATIONSHIPS HAS, DIAGNOSIS TO receptionist;
+GRANT DELETE ON GRAPH healthcare RELATIONSHIPS HAS, DIAGNOSIS TO receptionist;
+----
+====
+
+[NOTE]
+Privileges that were granted or denied earlier can be revoked using the `REVOKE` command.
+See link:/docs/cypher-manual/4.4/access-control/manage-privileges#access-control-revoke-privileges[the Cypher Manual -> The `REVOKE` command].
+
+=== Privileges of nurses
+
+As previously described, nurses have the capabilities of both doctors and receptionists.
+As such it would be tempting to assign them both the `doctor` and the `receptionist` roles.
+However, this might not have the effect you would expect.
+If those two roles were created with `GRANT` privileges only, combining them would be simply cumulative.
+But it turns out the doctor contains some `DENY` privileges, and these always overrule `GRANT`.
+This means that the nurse will still have the same restrictions as a doctor, which is not what we wanted.
+
+To demonstrate this, let's give it a try:
+
+====
+[source, cypher]
+----
+neo4j@system> GRANT ROLE doctor, receptionist TO daniel;
+----
+====
+
+Now we can see that the user 'Daniel' has a combined set of privileges:
+
+====
+[source, cypher, role=systemdb]
+----
+SHOW USER daniel PRIVILEGES AS COMMANDS;
+----
+----
++---------------------------------------------------------------------------+
+| command |
++---------------------------------------------------------------------------+
+| "GRANT ACCESS ON HOME DATABASE TO $role" |
+| "GRANT ACCESS ON DATABASE `healthcare` TO $role" |
+| "GRANT EXECUTE PROCEDURE * ON DBMS TO $role" |
+| "GRANT EXECUTE FUNCTION * ON DBMS TO $role" |
+| "GRANT TRAVERSE ON GRAPH `healthcare` NODE * TO $role" |
+| "GRANT TRAVERSE ON GRAPH `healthcare` RELATIONSHIP * TO $role" |
+| "GRANT READ {*} ON GRAPH `healthcare` NODE * TO $role" |
+| "GRANT READ {*} ON GRAPH `healthcare` RELATIONSHIP * TO $role" |
+| "GRANT MATCH {*} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "GRANT WRITE ON GRAPH `healthcare` TO $role" |
+| "GRANT SET PROPERTY {*} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "GRANT CREATE ON GRAPH `healthcare` NODE Patient TO $role" |
+| "GRANT DELETE ON GRAPH `healthcare` NODE Patient TO $role" |
+| "DENY READ {address} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "DENY SET PROPERTY {address} ON GRAPH `healthcare` NODE Patient TO $role" |
++---------------------------------------------------------------------------+
+----
+====
+
+[NOTE]
+Privileges that were granted or denied earlier can be revoked using the `REVOKE` command.
+See link:/docs/cypher-manual/4.4/access-control/manage-privileges#access-control-revoke-privileges[the Cypher Manual -> The `REVOKE` command].
+
+Now the intention is that a nurse can perform the actions of a receptionist.
+This would mean they should be able to read and write the `address` field of the `Patient` nodes.
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.dateOfBirth < date('1972-06-12')
+RETURN n.name, n.ssn, n.address, n.dateOfBirth;
+----
+----
++-------------------------------------------------------+
+| n.name | n.ssn | n.address | n.dateOfBirth |
++-------------------------------------------------------+
+| "Jane Anderson" | 1234572 | NULL | 1971-05-26 |
+| "Mark Stone" | 1234586 | NULL | 1972-06-07 |
+| "Joe Smith" | 1234595 | NULL | 1970-12-28 |
+| "Joe Jackson" | 1234603 | NULL | 1970-08-31 |
+| "Jane Jackson" | 1234628 | NULL | 1972-01-31 |
+| "Mary Anderson" | 1234632 | NULL | 1971-01-07 |
+| "Jack Svensson" | 1234639 | NULL | 1970-01-06 |
++-------------------------------------------------------+
+----
+
+Clearly the `address` field is invisible.
+This is due to the `DENIED` privileges we could see in the table earlier.
+If we tried to write to the address field we would receive an error.
+This is not the intended behavior.
+We have two choices to correct otherwise:
+
+* We could redefine the `doctor` role with only grants, requiring that we define each Patient property we wish the doctor to be able to read.
+* We can redefine the `nurse` role with the actual intended behavior.
+
+It turns out that the latter choice is by far the simplest.
+The nurse is essentially the doctor without the `address` restrictions:
+
+====
+[source, cypher, role=systemdb]
+----
+CREATE ROLE nurse
+GRANT TRAVERSE ON GRAPH healthcare TO nurse;
+GRANT READ {*} ON GRAPH healthcare TO nurse;
+GRANT WRITE ON GRAPH healthcare TO nurse;
+----
+====
+
+Now let's assign this role to Daniel and test the new behavior:
+
+====
+[source, cypher, role=systemdb]
+----
+REVOKE ROLE doctor FROM daniel;
+REVOKE ROLE receptionist FROM daniel;
+GRANT ROLE nurse TO daniel;
+----
+====
+
+When the _improved_ nurse Daniel takes another look at the patient records, he will see the `address` fields:
+
+[source, cypher]
+----
+MATCH (n:Patient)
+ WHERE n.dateOfBirth < date('1972-06-12')
+RETURN n.name, n.ssn, n.address, n.dateOfBirth;
+----
+----
++----------------------------------------------------------------------+
+| n.name | n.ssn | n.address | n.dateOfBirth |
++----------------------------------------------------------------------+
+| "Jane Anderson" | 1234572 | "1 secret way, downtown" | 1971-05-26 |
+| "Mark Stone" | 1234586 | "1 secret way, downtown" | 1972-06-07 |
+| "Joe Smith" | 1234595 | "1 secret way, downtown" | 1970-12-28 |
+| "Joe Jackson" | 1234603 | "1 secret way, downtown" | 1970-08-31 |
+| "Jane Jackson" | 1234628 | "1 secret way, downtown" | 1972-01-31 |
+| "Mary Anderson" | 1234632 | "1 secret way, downtown" | 1971-01-07 |
+| "Jack Svensson" | 1234639 | "1 secret way, downtown" | 1970-01-06 |
++----------------------------------------------------------------------+
+----
+
+Now Daniel can see the previously hidden `address` field.
+The other main action we want the `nurse` to be able to perform, is the primary `doctor` action of saving a diagnosis to the database:
+
+[source, cypher]
+----
+WITH date(datetime({epochmillis:timestamp()})) AS today
+MATCH (p:Patient)
+ WHERE p.ssn = 1234657
+MATCH (d:Disease)
+ WHERE d.name = "Chronic Placeboitis"
+MERGE (p)-[i:DIAGNOSIS {by: 'Daniel'}]->(d)
+ ON CREATE SET i.date = today
+RETURN p.name, d.name, i.by, i.date;
+----
+----
++------------------------------------------------------------------+
+| p.name | d.name | i.by | i.date |
++------------------------------------------------------------------+
+| "Sally Anderson" | "Chronic Placeboitis" | "Daniel" | 2020-05-29 |
++------------------------------------------------------------------+
+----
+
+Performing an action otherwise reserved for the `doctor` role involves more responsibility for the `nurse`.
+Perhaps it is not desirable to entrust all nurses with this option, which is why we can divide the nurses into _senior_ and _junior_ nurses.
+Daniel is currently a senior nurse.
+
+=== Privileges of junior nurses
+
+When we tried to create the senior nurse by combining the `doctor` and `receptionist` roles, that did not work out.
+As previously mentioned, it would work to combine two roles if the intention is to increase capabilities and the roles were created with `GRANT` privileges only.
+It is also possible to combine two roles if the intention is to reduce capabilities and the combination brings in `DENY` privileges.
+
+Consider this case, we would like a junior nurse to be able to perform the same actions as a senior nurse, but not be able to save diagnoses.
+We could create a special role that contains specifically only the additional restrictions:
+
+====
+[source, cypher, role=systemdb]
+----
+CREATE ROLE disableDiagnoses;
+DENY CREATE ON GRAPH healthcare RELATIONSHIPS DIAGNOSIS TO disableDiagnoses;
+----
+====
+
+Now let's assign this role to Daniel and test the new behaviour:
+
+====
+[source, cypher, role=systemdb]
+----
+GRANT ROLE disableDiagnoses TO daniel;
+----
+====
+
+If we look at what privileges Daniel now has, it will be the combination of the two roles `nurse` and `disableDiagnoses`:
+
+====
+[source, cypher, role=systemdb]
+----
+neo4j@system> SHOW USER daniel PRIVILEGES AS COMMANDS;
+----
+----
++---------------------------------------------------------------------+
+| command |
++---------------------------------------------------------------------+
+| "GRANT ACCESS ON HOME DATABASE TO $role" |
+| "GRANT ACCESS ON DATABASE `healthcare` TO $role" |
+| "GRANT EXECUTE PROCEDURE * ON DBMS TO $role" |
+| "GRANT EXECUTE FUNCTION * ON DBMS TO $role" |
+| "GRANT TRAVERSE ON GRAPH `healthcare` NODE * TO $role" |
+| "GRANT TRAVERSE ON GRAPH `healthcare` RELATIONSHIP * TO $role" |
+| "GRANT READ {*} ON GRAPH `healthcare` NODE * TO $role" |
+| "GRANT READ {*} ON GRAPH `healthcare` RELATIONSHIP * TO $role" |
+| "GRANT WRITE ON GRAPH `healthcare` TO $role" |
+| "DENY CREATE ON GRAPH `healthcare` RELATIONSHIP DIAGNOSIS TO $role" |
++---------------------------------------------------------------------+
+----
+====
+
+Daniel can still see address fields, and can even perform the diagnosis investigation that the `doctor` can perform:
+
+[source, cypher]
+----
+MATCH (n:Patient)-[:HAS]->(s:Symptom)-[:OF]->(d:Disease)
+WHERE n.ssn = 1234650
+RETURN n.ssn, n.name, d.name, count(s) AS score ORDER BY score DESC;
+----
+----
++--------------------------------------------------------+
+| n.ssn | n.name | d.name | score |
++--------------------------------------------------------+
+| 1234650 | "Mark Smith" | "Chronic Whatitis" | 3 |
+| 1234650 | "Mark Smith" | "Chronic Someitis" | 3 |
+| 1234650 | "Mark Smith" | "Acute Someitis" | 2 |
+| 1234650 | "Mark Smith" | "Chronic Otheritis" | 2 |
+| 1234650 | "Mark Smith" | "Chronic Yellowitis" | 2 |
+| 1234650 | "Mark Smith" | "Chronic Placeboitis" | 2 |
+| 1234650 | "Mark Smith" | "Acute Otheritis" | 2 |
+| 1234650 | "Mark Smith" | "Chronic Argitis" | 2 |
+| 1234650 | "Mark Smith" | "Acute Placeboitis" | 2 |
+| 1234650 | "Mark Smith" | "Acute Yellowitis" | 1 |
+| 1234650 | "Mark Smith" | "Acute Argitis" | 1 |
+| 1234650 | "Mark Smith" | "Acute Whatitis" | 1 |
++--------------------------------------------------------+
+----
+
+But when he tries to save a diagnosis to the database, he will be denied:
+
+[source, cypher]
+----
+WITH date(datetime({epochmillis:timestamp()})) AS today
+MATCH (p:Patient)
+ WHERE p.ssn = 1234650
+MATCH (d:Disease)
+ WHERE d.name = "Chronic Placeboitis"
+MERGE (p)-[i:DIAGNOSIS {by: 'Daniel'}]->(d)
+ ON CREATE SET i.date = today
+RETURN p.name, d.name, i.by, i.date;
+----
+[role=erroronlyqueryresult]
+----
+Create relationship with type 'DIAGNOSIS' is not allowed for user 'daniel' with roles [PUBLIC, disableDiagnoses, nurse].
+----
+
+Promoting Daniel back to senior nurse will be as simple as revoking the role that introduced the restriction:
+
+====
+[source, cypher, role=systemdb]
+----
+REVOKE ROLE disableDiagnoses FROM daniel;
+----
+====
+
+=== Building a custom administrator role
+
+Originally we created the `itadmin` role by copying the built-in `admin` role and adding restrictions.
+However, we have also shown cases where having denys can be less convenient than only having grants.
+So can we instead build the administrator role from the ground up?
+
+Let's review the purpose of this role.
+The intention is that Tina, the administrator, can create new users and assign them to the product roles.
+We can create a new role called `userManager` and grant it the appropriate privileges:
+
+====
+[source, cypher, role=systemdb]
+----
+CREATE ROLE userManager;
+GRANT USER MANAGEMENT ON DBMS TO userManager;
+GRANT ROLE MANAGEMENT ON DBMS TO userManager;
+GRANT SHOW PRIVILEGE ON DBMS TO userManager;
+----
+====
+
+We need to revoke the `itadmin` role from Tina and grant her the `userManager` role instead:
+
+====
+[source, cypher, role=systemdb]
+----
+REVOKE ROLE itadmin FROM tina
+GRANT ROLE userManager TO tina
+----
+====
+
+The three privileges we've granted will allow:
+
+* `USER MANAGEMENT` allows creating, updating and dropping users
+* `ROLE MANAGEMENT` allows creating, updating, and dropping roles as well as assigning roles to users
+* `SHOW PRIVILEGE` allows listing the users privileges
+
+
+Listing Tina's new privileges should show a much shorter list than when she was a more powerful administrator:
+
+====
+[source, cypher, role=systemdb]
+----
+neo4j@system> SHOW USER tina PRIVILEGES AS COMMANDS;
+----
+
+----
++--------------------------------------------------+
+| command |
++--------------------------------------------------+
+| "GRANT ACCESS ON HOME DATABASE TO $role" |
+| "GRANT ACCESS ON DATABASE `healthcare` TO $role" |
+| "GRANT EXECUTE PROCEDURE * ON DBMS TO $role" |
+| "GRANT EXECUTE FUNCTION * ON DBMS TO $role" |
+| "GRANT ROLE MANAGEMENT ON DBMS TO $role" |
+| "GRANT USER MANAGEMENT ON DBMS TO $role" |
+| "GRANT SHOW PRIVILEGE ON DBMS TO $role" |
++--------------------------------------------------+
+----
+====
+
+[NOTE]
+We have not granted any other privilege management privileges.
+How much power this role should have would depend on the requirements of the system.
+Refer to the section link:/docs/cypher-manual/4.4/access-control/built-in-roles#access-control-built-in-roles-admin[Cypher Manual -> The `admin` role] for a complete list of privileges to consider.
+
+
+Now Tina should be able to create new users and assign them to roles:
+
+====
+[source, cypher, role=systemdb]
+----
+CREATE USER sally SET PASSWORD 'secret' CHANGE REQUIRED;
+GRANT ROLE receptionist TO sally;
+SHOW USER sally PRIVILEGES AS COMMANDS;
+----
+====
+
+====
+----
++----------------------------------------------------------------------+
+| command |
++----------------------------------------------------------------------+
+| "GRANT ACCESS ON HOME DATABASE TO $role" |
+| "GRANT ACCESS ON DATABASE `healthcare` TO $role" |
+| "GRANT EXECUTE PROCEDURE * ON DBMS TO $role" |
+| "GRANT EXECUTE FUNCTION * ON DBMS TO $role" |
+| "GRANT MATCH {*} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "GRANT SET PROPERTY {*} ON GRAPH `healthcare` NODE Patient TO $role" |
+| "GRANT CREATE ON GRAPH `healthcare` NODE Patient TO $role" |
+| "GRANT DELETE ON GRAPH `healthcare` NODE Patient TO $role" |
++----------------------------------------------------------------------+
+----
+====
diff --git a/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc b/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc
new file mode 100644
index 000000000..9d12c896a
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/built-in-roles.adoc
@@ -0,0 +1,411 @@
+[role=enterprise-edition]
+[[auth-built-in-roles]]
+= Built-in roles
+:description: This section describes the roles that come pre-defined with Neo4j.
+
+//Check Mark
+:check-mark: icon:check[]
+
+Neo4j provides built-in roles with default privileges. The built-in roles and the default privileges are:
+
+[.compact]
+`PUBLIC`::
+* Access to the home database.
+* Allows executing procedures with the users own privileges.
+* Allows executing user-defined functions with the users own privileges.
+`reader`::
+* Access to all databases.
+* Traverse and read on the data graph (all nodes, relationships, properties).
+`editor`::
+* Access to all databases.
+* Traverse, read, and write on the data graph.
+* Write access limited to creating and changing *existing* property keys, node labels, and relationship types of the graph.
+In other words, the `editor` role cannot add to the schema but can only make changes to already existing objects.
+`publisher`::
+* Access to all databases.
+* Traverse, read, and write on the data graph.
+`architect`::
+* Access to all databases.
+* Traverse, read, and write on the data graph.
+* Create/drop/show indexes and constraints along with any other future schema constructs.
+`admin`::
+* Access to all databases.
+* Traverse, read, and write on the data graph.
+* Create/drop/show indexes and constraints along with any other future schema constructs.
+* Allows executing procedures with the users own privileges or boosted privileges.
+* Allows executing admin procedures.
+* Allows executing user-defined functions with the users own privileges or boosted privileges.
+* View/terminate queries.
+* Manage databases, users, roles, and privileges.
+
+
+All users will be assigned the `PUBLIC` role, which by default does not give any rights or capabilities regarding the data, not even read privileges.
+A user may have more than one assigned role, and the union of these determine what action(s) on the data may be undertaken by the user.
+For instance, a user assigned to the `reader` role will be able to execute procedures because all users are also
+assigned to the `PUBLIC` role, which enables that capability.
+
+When an administrator suspends or deletes another user, the following rules apply:
+
+* Administrators can suspend or delete any other user (including other administrators), but not themselves.
+* The user will no longer be able to log back in (until re-activated by an administrator if suspended).
+* There is no need to remove assigned roles from a user prior to deleting the user.
+
+[NOTE]
+--
+Deleting a user will not automatically terminate associated connections, sessions, transactions, or queries.
+--
+
+The set of actions on the data and database prescribed by each role are described below.
+The subset of the functionality which is available with Community Edition is also included:
+
+[[auth-built-in-roles-overview]]
+.Native roles overview
+[options="header" cols="16d,^12a,^12a,^12a,^12a,^12a,^12a,^12a"]
+|===
+| Action
+| `reader`
+| `editor`
+| `publisher`
+| `architect`
+| `admin`
+| `PUBLIC`
+| Available in Community Edition
+
+| Change own password
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+
+
+| View own details
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+
+
+| Read data
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| Execute procedures
+|
+|
+|
+|
+| {check-mark}
+| {check-mark}
+| {check-mark}
+
+| Execute functions
+|
+|
+|
+|
+| {check-mark}
+| {check-mark}
+| {check-mark}
+
+| Execute admin procedures
+|
+|
+|
+|
+| {check-mark}
+|
+| {check-mark}
+
+| View own queries
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+|
+
+| Terminate own queries
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+|
+
+| Write/update/delete existing data
+|
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| Create new types of properties key
+|
+|
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| Create new types of nodes labels
+|
+|
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| Create new types of relationship types
+|
+|
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| Create/drop/show index/constraint
+|
+|
+|
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| Create/delete user
+|
+|
+|
+|
+| {check-mark}
+|
+| {check-mark}
+
+| Change another user's name
+|
+|
+|
+|
+| {check-mark}
+|
+| {check-mark}
+
+| Change another user's password
+|
+|
+|
+|
+| {check-mark}
+|
+| {check-mark}
+
+| Change another user's home database
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Suspend/activate user
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Create/drop roles
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Change role names
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Assign/remove role to/from user
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Create/drop/alter databases
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Start/stop databases
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Manage database access
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Access home database
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+
+| Access all databases
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+| {check-mark}
+
+| View all users
+|
+|
+|
+|
+| {check-mark}
+|
+| {check-mark}
+
+| View all roles
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| View all roles for a user
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| View all users for a role
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| View all queries
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| View all databases
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| View own privileges
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+| {check-mark}
+|
+
+| View another user's privileges
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Grant/deny/revoke privileges
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Terminate all queries
+|
+|
+|
+|
+| {check-mark}
+|
+|
+
+| Dynamically change configuration (see xref:configuration/dynamic-settings.adoc[Dynamic settings])
+|
+|
+|
+|
+| {check-mark}
+|
+|
+|===
+
+More information about the built-in roles and their privileges can be found in
+link:/docs/cypher-manual/4.4/access-control/built-in-roles[Neo4j Cypher Manual].
diff --git a/modules/ROOT/pages/authentication-authorization/index.adoc b/modules/ROOT/pages/authentication-authorization/index.adoc
new file mode 100644
index 000000000..379b1482b
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/index.adoc
@@ -0,0 +1,26 @@
+[role=enterprise-edition]
+[[auth]]
+= Authentication and authorization
+:description: This chapter describes authentication and authorization in Neo4j.
+
+Ensure that your Neo4j deployment adheres to your company's information security guidelines by setting up the appropriate authentication and authorization rules.
+
+Ths section describes the following:
+
+* xref:authentication-authorization/introduction.adoc[Introduction]
+* xref:authentication-authorization/built-in-roles.adoc[Built-in roles]
+* xref:authentication-authorization/access-control.adoc[Fine-grained access control]
+* xref:authentication-authorization/ldap-integration.adoc[Integration with LDAP directory services]
+* xref:authentication-authorization/sso-integration.adoc[Integration with Single Sign-On (SSO) services]
+* xref:authentication-authorization/manage-execute-permissions.adoc[Manage procedure and user-defined function permissions]
+* xref:authentication-authorization/terminology.adoc[Terminology]
+
+
+[NOTE]
+--
+The functionality described in this section is applicable to Enterprise Edition.
+A limited set of user management functions are also available in Community Edition.
+xref:authentication-authorization/built-in-roles.adoc#auth-built-in-roles-overview[Native roles overview] gives a quick overview of these.
+--
+
+
diff --git a/modules/ROOT/pages/authentication-authorization/introduction.adoc b/modules/ROOT/pages/authentication-authorization/introduction.adoc
new file mode 100644
index 000000000..19fb2c4e0
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/introduction.adoc
@@ -0,0 +1,47 @@
+[role=enterprise-edition]
+[[auth-introduction]]
+= Introduction
+:description: This section provides an overview of authentication and authorization in Neo4j.
+
+Authentication is the process of ensuring that a user is who the user claims to be, while authorization pertains to checking whether the authenticated user is allowed to perform a certain action.
+Authorization is managed using role-based access control (_RBAC_).
+Permissions that define access control are assigned to roles, which are in turn assigned to users.
+
+Neo4j has the following auth providers, that can perform user authentication and authorization:
+
+*Native auth provider*::
+Neo4j provides a native auth provider that stores user and role information in the `system` database.
+The following parameters control this provider:
++
+====
+* xref:reference/configuration-settings.adoc#config_dbms.security.auth_enabled[`dbms.security.auth_enabled`] (Default: `true`) -- Enable auth requirement to access Neo4j. +
++
+[NOTE]
+If you need to disable authentication, for example, to recover an `admin` user password or assign a user to the `admin` role, make sure you block all network connections during the recovery phase so users can connect to Neo4j only via `localhost`.
+For more information, see xref:configuration/password-and-user-recovery.adoc[Password and user recovery].
+
+* xref:reference/configuration-settings.adoc#config_dbms.security.auth_lock_time[`dbms.security.auth_lock_time`] (Default: `5s`) -- The amount of time a user account is locked after a configured number of unsuccessful authentication attempts.
+* xref:reference/configuration-settings.adoc#config_dbms.security.auth_max_failed_attempts[`dbms.security.auth_max_failed_attempts`] (Default: `3`) -- The maximum number of unsuccessful authentication attempts before imposing a user lock for a configured amount of time. +
+When triggered, Neo4j logs an error containing a timestamp and the message `failed to log in: too many failed attempts` in the _security.log_.
+====
++
+The Cypher commands to manage users, roles, and permissions are described in detail in link:/docs/cypher-manual/{neo4j-version}/access-control/[Cypher Manual -> Administration].
+Various scenarios that illustrate the use of the native auth provider are available in xref:authentication-authorization/access-control.adoc[Fine-grained access control].
+
+*LDAP auth provider*::
+Another way of controlling authentication and authorization is through external security software such as Active Directory or OpenLDAP, which is accessed via the built-in LDAP connector.
+A description of the LDAP plugin using Active Directory is available in xref:authentication-authorization/ldap-integration.adoc[Integration with LDAP directory services].
+
+*Single Sign-On provider*::
+Some clients wish to centrally manage authentication and authorization for their systems in an identity provider which provides single sign-on for their other systems.
+Neo4j supports the popular OpenID Connect mechanism for integrating with identity providers and configuration for that is described in xref:authentication-authorization/sso-integration.adoc[Integration with Single Sign-On Services].
+
+*Custom-built plugin auth providers*::
+For clients with specific requirements not satisfied with either native or LDAP, Neo4j provides a plugin option for building custom integrations.
+It is recommended that this option is used as part of a custom delivery as negotiated with Neo4j Professional Services.
+The plugin is described in link:/docs/java-reference/4.4/extending-neo4j/security-plugins#extending-neo4j-security-plugins[Java Reference -> Authentication and authorization plugins].
+
+
+*Kerberos authentication and single sign-on*::
+In addition to LDAP, Native and custom providers, Neo4j supports Kerberos for authentication and single sign-on.
+Kerberos support is provided via the link:/docs/kerberos-add-on/current/[Neo4j Kerberos Add-On].
diff --git a/modules/ROOT/pages/authentication-authorization/ldap-integration.adoc b/modules/ROOT/pages/authentication-authorization/ldap-integration.adoc
new file mode 100644
index 000000000..f96623584
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/ldap-integration.adoc
@@ -0,0 +1,440 @@
+[role=enterprise-edition]
+[[auth-ldap-integration]]
+= Integration with LDAP directory services
+:description: This section describes Neo4j support for integrating with LDAP systems.
+
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-introduction[Introduction]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-parameters[LDAP configuration parameters]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-configure-provider[Set Neo4j to use LDAP]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-map-ldap-roles[Map the LDAP groups to the Neo4j roles]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-configure-provider-ad[Configure Neo4j to use Active Directory]
+** xref:authentication-authorization/ldap-integration.adoc#auth-ldap-configure-provider-ad-uid[Configure Neo4j to support LDAP user ID authentication]
+** xref:authentication-authorization/ldap-integration.adoc#auth-ldap-configure-provider-ad-sysaccount[Configure Neo4j to support attribute authentication]
+** xref:authentication-authorization/ldap-integration.adoc#auth-ldap-configure-provider-ad-nosysaccount[Configure Neo4j to support `sAMAccountName` authentication by setting `user_dn_template`]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-configure-provider-openldap[Configure Neo4j to use OpenLDAP]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-search[Verify the LDAP configuration]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-clear-auth-cache[The auth cache]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-ad-encrypted[Available methods of encryption]
+** xref:authentication-authorization/ldap-integration.adoc#auth-ldap-encrypted-starttls[Use LDAP with encryption via StartTLS]
+** xref:authentication-authorization/ldap-integration.adoc#auth-ldap-encrypted-ldaps[Use LDAP with encrypted LDAPS]
+* xref:authentication-authorization/ldap-integration.adoc#auth-ldap-self-signed-certificate[Use a self-signed certificate (SSL) in a test environment]
+
+
+[[auth-ldap-introduction]]
+== Introduction
+
+Neo4j supports LDAP, which allows for integration with Active Directory (AD), OpenLDAP, or other LDAP-compatible authentication services.
+This means that you use the LDAP service for managing federated users, while the native Neo4j user and role administration are completely turned off.
+
+The following configuration settings are important to consider when configuring LDAP.
+For a more detailed overview of the LDAP configuration options, see xref:reference/configuration-settings.adoc[Configuration settings].
+
+[[auth-ldap-parameters]]
+== LDAP dynamic configuration settings
+
+The following configuration settings can be updated while the database is running, see xref:configuration/dynamic-settings.adoc[Dynamic settings].
+Altering any of these settings clears the authentication and authorization cache.
+
+[options="header",cols="<,<,<"]
+|===
+| Parameter name
+| Default value
+| Description
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authentication.user_dn_template[dbms.security.ldap.authentication.user_dn_template]
+| `+uid={0},ou=users,dc=example,dc=com+`
+| Convert usernames into LDAP-specific fully qualified names required for logging in.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authorization.user_search_base[dbms.security.ldap.authorization.user_search_base]
+| `ou=users,dc=example,dc=com`
+| Set the base object or named context to search for user objects.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authorization.user_search_filter[dbms.security.ldap.authorization.user_search_filter]
+| `+(&(objectClass=*)(uid={0}))+`
+| Set an LDAP search filter for a user principal.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authorization.group_membership_attributes[dbms.security.ldap.authorization.group_membership_attributes]
+| `memberOf`
+| List attribute names on a user object that contains groups to be used for mapping to roles.
+Common values: `memberOf` and `gidNumber`.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authorization.group_to_role_mapping[dbms.security.ldap.authorization.group_to_role_mapping]
+|
+| List an authorization mapping from groups to the pre-defined built-in roles `admin`, `architect`, `publisher`, `editor`, and `reader`, or to any other custom-defined roles.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authentication.attribute[dbms.security.ldap.authentication.attribute]
+| `samaccountname`
+| Set the attribute to search for users with a system account.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authorization.access_permitted_group[dbms.security.ldap.authorization.access_permitted_group]
+|
+| Set an LDAP group of users with access rights.
+Users passing authentication are mapped to at least the `PUBLIC` role in addition to any roles assigned by the
+xref:authentication-authorization/ldap-integration.adoc#auth-ldap-map-ldap-roles[group to role mapping] and have access to the database that those roles provide.
+If this attribute is set, users not part of
+this LDAP group will fail authentication, even if their credentials are correct.
+|===
+
+All settings are defined at server startup time in the default configuration file _xref:configuration/neo4j-conf.adoc[neo4j.conf]_ or can be modified at
+runtime using xref:reference/procedures.adoc#procedure_dbms_setconfigvalue[`dbms.setConfigValue()`].
+
+
+[[auth-ldap-configure-provider]]
+== Set Neo4j to use LDAP
+
+First, you configure Neo4j to use LDAP as an authentication and authorization provider.
+
+. Uncomment the setting `dbms.security.auth_enabled=false` and change its value to `true` to turn on the security feature.
+. Uncomment the settings `dbms.security.authentication_providers` and `dbms.security.authorization_providers` and change their value to `ldap`.
+This way, the LDAP connector is used as a security provider for both authentication and authorization.
+
+[[auth-ldap-map-ldap-roles]]
+== Map the LDAP groups to the Neo4j roles
+
+To access the user and role management procedures, you have to map the LDAP groups to the xref:authentication-authorization/built-in-roles.adoc[Neo4j built-in] and custom-defined roles.
+To do that, you need to know what privileges the Neo4j roles have, and based on these privileges, to create the mapping to the groups defined in the LDAP server.
+The map must be formatted as a semicolon separated list of key-value pairs, where the key is a comma-separated list of the LDAP group names and the value is a comma-separated list of the corresponding role names.
+For example, `group1=role1;group2=role2;group3=role3,role4,role5;group4,group5=role6`.
+
+.Example of LDAP groups to Neo4j roles mapping
+====
+[source, role=noheader]
+----
+dbms.security.ldap.authorization.group_to_role_mapping=\
+ "cn=Neo4j Read Only,cn=users,dc=example,dc=com" = reader; \ #<1>
+ "cn=Neo4j Read-Write,cn=users,dc=example,dc=com" = editor,publisher; \ #<2>
+ "cn=Neo4j Read-Write,cn=users,dc=example,dc=com","cn=Neo4j Create Data,cn=users,dc=example,dc=com" = publisher; \ #<3>
+ "cn=Neo4j Create Data,cn=users,dc=example,dc=com","cn=Neo4j Schema Manager,cn=users,dc=example,dc=com" = architect; \
+ "cn=Neo4j Administrator,cn=users,dc=example,dc=com" = admin; \
+ "cn=Neo4j Procedures,cn=users,dc=neo4j,dc=com" = rolename #<4>
+----
+
+<1> Mapping of an LDAP group to a Neo4j built-in role.
+<2> Mapping of an LDAP group to two Neo4j built-in roles.
+<3> Mapping of two LDAP groups to a Neo4j built-in role.
+<4> Mapping of an LDAP group to a custom-defined role.
+Custom-defined roles, such as `rolename`, must be explicitly created using the `CREATE ROLE rolename` command before they can be used to grant privileges.
+See link:/docs/cypher-manual/4.4/access-control/manage-users[the Cypher Manual -> Creating roles].
+====
+
+[[auth-ldap-configure-provider-ad]]
+== Configure Neo4j to use Active Directory
+
+You configure Neo4j to use the LDAP security provider to access and manage your Active Directory.
+There are three alternative ways to do that depending on your specific use case.
+
+[[auth-ldap-configure-provider-ad-uid]]
+=== Configure Neo4j to support LDAP user ID authentication
+
+This option allows users to log in with their LDAP user ID.
+
+In the _neo4j.conf_ file, uncomment and configure the following settings:
+
+. Configure LDAP to point to the AD server:
++
+[source, properties]
+----
+dbms.security.ldap.host=ldap://myactivedirectory.example.com
+----
+
+. Provide details on the user structure of the LDAP directory:
++
+[source, properties]
+----
+dbms.security.ldap.authentication.user_dn_template=cn={0},cn=Users,dc=example,dc=com
+dbms.security.ldap.authorization.user_search_base=cn=Users,dc=example,dc=com
+dbms.security.ldap.authorization.user_search_filter=(&(objectClass=*)(cn={0}))
+dbms.security.ldap.authorization.group_membership_attributes=memberOf
+----
+
+. Map the groups in the LDAP system to the Neo4j built-in and custom roles.
+See xref:authentication-authorization/ldap-integration.adoc#auth-ldap-map-ldap-roles[Map the LDAP groups to the Neo4j roles].
+
+[[auth-ldap-configure-provider-ad-sysaccount]]
+=== Configure Neo4j to support attribute authentication
+
+This is an alternative configuration for Active Directory that allows users to log in by providing an attribute to search for, by default `sAMAccountName`.
+The attribute has to be unique to be used as a lookup.
+You create a system account that has read-only access to the parts of the LDAP directory that you want.
+However, it does not need to have access rights to Neo4j or any other systems.
+
+In the _neo4j.conf_ file, uncomment and configure the following settings:
+
+. Configure LDAP to point to the AD server:
++
+[source, properties]
+----
+dbms.security.ldap.host=ldap://myactivedirectory.example.com
+----
+
+. Provide details on the user structure of the LDAP directory (replacing `myattribute` with the actual attribute name):
++
+[source, properties]
+----
+dbms.security.ldap.authorization.user_search_base=cn=Users,dc=example,dc=com
+dbms.security.ldap.authorization.user_search_filter=(&(objectClass=*)(myattribute={0}))
+dbms.security.ldap.authorization.group_membership_attributes=memberOf
+----
+
+. Map the groups in the LDAP system to the Neo4j built-in and custom roles.
+See xref:authentication-authorization/ldap-integration.adoc#auth-ldap-map-ldap-roles[Map the LDAP groups to the Neo4j roles].
+
+. Configure Neo4j to use a system account with read access to all users and groups in the LDAP server.
+
+.. Set `dbms.security.ldap.authorization.use_system_account` value to `true`.
+
+.. Set `dbms.security.ldap.authorization.system_username` value to the full Distinguished Name (DN) as the `dbms.security.ldap.authentication.user_dn_template` will not be applied to this username.
+For example,
++
+[source, properties]
+----
+dbms.security.ldap.authorization.system_username=cn=search-account,cn=Users,dc=example,dc=com
+----
+
+.. Configure the LDAP system account password.
++
+[source, properties]
+----
+dbms.security.ldap.authorization.system_password=mypassword
+----
+
+.. Configure which attribute to search for by adding the following lines to the _neo4j.conf_ file (replacing `myattribute` with the actual attribute name):
++
+[source, properties]
+----
+dbms.security.ldap.authentication.search_for_attribute=true
+dbms.security.ldap.authentication.attribute=myattribute
+----
+.. (Optional) Create an LDAP group to restrict authentication against the database to a subset of LDAP users:
++
+[source, properties]
+----
+dbms.security.ldap.authorization.access_permitted_group=cn=Neo4j Access,cn=users,dc=example,dc=com
+----
+
+[NOTE]
+Earlier Neo4j versions only supported `samaccountname` as a search attribute.
+This could be configured with `dbms.security.ldap.authentication.use_samaccountname`.
+That setting has been deprecated and replaced by `dbms.security.ldap.authentication.search_for_attribute`.
+
+[[auth-ldap-configure-provider-ad-nosysaccount]]
+=== Configure Neo4j to support `sAMAccountName` authentication by setting `user_dn_template`
+
+This is an alternative configuration for Active Directory that allows all users from the specified domain to log in using `sAMAccountName`.
+With this option, you do not have to create a system account and store a system username/password in the config file.
+Instead, you set `+{0}@example.com+` as a value of the `user_dn_template` to enable the authentication to start at the root domain.
+This way, the whole tree is checked to find the user, regardless of where it is located within the LDAP directory tree.
+
+In the _neo4j.conf_ file, uncomment and configure the following settings:
+
+. Configure LDAP to point to the AD server:
++
+[source, properties]
+----
+dbms.security.ldap.host=ldap://myactivedirectory.example.com
+----
+
+. Provide details on the user structure of the LDAP directory:
++
+[source, properties]
+----
+dbms.security.ldap.authentication.user_dn_template={0}@example.com
+dbms.security.ldap.authorization.user_search_base=dc=example,dc=com
+dbms.security.ldap.authorization.user_search_filter=(&(objectClass=user)(sAMAccountName={0}))
+dbms.security.ldap.authorization.group_membership_attributes=memberOf
+----
++
+
+. Map the groups in the LDAP system to the Neo4j built-in and custom roles.
+For more information, see xref:authentication-authorization/ldap-integration.adoc#auth-ldap-map-ldap-roles[Map the LDAP groups to the Neo4j roles].
+
+[NOTE]
+The setting `dbms.security.ldap.authentication.search_for_attribute` should be set to the default value of false.
+
+[[auth-ldap-configure-provider-openldap]]
+== Configure Neo4j to use OpenLDAP
+
+You configure the LDAP security provider to access and manage your OpenLDAP directory service.
+
+In the neo4j.conf file, uncomment and configure the following settings:
+
+. Configure LDAP to point to the OpenLDAP server:
++
+[source, properties]
+----
+dbms.security.ldap.host=myopenldap.example.com
+----
+
+. Provide details on the user structure of the LDAP directory:
++
+[source, properties]
+----
+dbms.security.ldap.authentication.user_dn_template=cn={0},ou=users,dc=example,dc=com
+dbms.security.ldap.authorization.user_search_base=ou=users,dc=example,dc=com
+dbms.security.ldap.authorization.user_search_filter=(&(objectClass=*)(uid={0}))
+dbms.security.ldap.authorization.group_membership_attributes=gidNumber
+----
+. (Optional) Create an LDAP group to restrict authentication against the database to a subset of LDAP users:
++
+[source, properties]
+----
+dbms.security.ldap.authorization.access_permitted_group=501
+----
+
+. Map the groups in the LDAP system to the Neo4j built-in and custom roles.
+For more information, see xref:authentication-authorization/ldap-integration.adoc#auth-ldap-map-ldap-roles[Map the LDAP groups to the Neo4j roles].
+
+[[auth-ldap-search]]
+== Verify the LDAP configuration
+
+You can verify that your LDAP configuration is correct, and that the LDAP server responds, by using the LDAP command-line tool `ldapsearch`.
+
+The `ldapsearch` command accepts the LDAP configuration setting values as input and verifies both the authentication (using the `simple` mechanism) and authorization of a user.
+See the https://docs.ldap.com/ldap-sdk/docs/tool-usages/ldapsearch.html[ldapsearch official documentation^] for more advanced usage and how to use SASL authentication mechanisms.
+
+. Verify the authentication and authorization of a user.
+For example, `john`.
+
+* With `dbms.security.ldap.authorization.use_system_account=false` (default):
++
+[source, shell, role=noplay]
+----
+# ldapsearch -v -H ldap:// -x -D -W -b ""
+
+ldapsearch -v -H ldap://myactivedirectory.example.com:389 -x -D cn=john,cn=Users,dc=example,dc=com -W -b cn=Users,dc=example,dc=com "(&(objectClass=*)(cn=john))" memberOf
+----
+
+* With `dbms.security.ldap.authorization.use_system_account=true`:
++
+[source, shell, role=noplay]
+----
+# ldapsearch -v -H ldap:// -x -D -w -b ""
+
+ldapsearch -v -H ldap://myactivedirectory.example.com:389 -x -D cn=search-account,cn=Users,dc=example,dc=com -w mypassword -b cn=Users,dc=example,dc=com "(&(objectClass=*)(cn=john))" memberOf
+----
+
+. Verify that the value of the returned membership attribute is a group that is mapped to a role in `dbms.security.ldap.authorization.group_to_role_mapping`.
++
+[source, properties]
+----
+# extended LDIF
+#
+# LDAPv3
+# base with scope subtree
+# filter: (cn=john)
+# requesting: memberOf
+#
+
+# john, Users, example.com
+dn: CN=john,CN=Users,DC=example,DC=com
+memberOf: CN=Neo4j Read Only,CN=Users,DC=example,DC=com
+
+# search result
+search: 2
+result: 0 Success
+
+# numResponses: 2
+# numEntries: 1
+----
+
+[[auth-ldap-clear-auth-cache]]
+== The auth cache
+The _auth cache_ is the mechanism by which Neo4j caches the result of authentication via the LDAP server in order to aid performance.
+It is configured with the parameters `xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authentication.cache_enabled[dbms.security.ldap.authentication.cache_enabled]`, and `xref:reference/configuration-settings.adoc#config_dbms.security.auth_cache_ttl[dbms.security.auth_cache_ttl]`.
+
+[source, properties]
+----
+# Turn on authentication caching to ensure performance.
+
+dbms.security.ldap.authentication.cache_enabled=true
+dbms.security.auth_cache_ttl=10m
+----
+.Auth cache parameters
+[options="header", cols="<,<,<"]
+|===
+| Parameter name
+| Default value
+| Description
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.ldap.authentication.cache_enabled[dbms.security.ldap.authentication.cache_enabled]
+| `true`
+| Determines whether or not to cache the result of authentication via the LDAP server.
+
+Whether authentication caching should be enabled or not must be considered in view of your company's security guidelines.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.auth_cache_ttl[dbms.security.auth_cache_ttl]
+| `600 seconds`
+| Is the time to live (TTL) for cached authentication and authorization info.
+
+Setting the TTL to 0 disables all auth caching.
+
+A short TTL requires more frequent re-authentication and re-authorization, which can impact performance.
+
+A very long TTL means that changes to the users settings on an LDAP server may not be reflected in the Neo4j authorization behaviour in a timely manner.
+
+Valid units are `ms`, `s`, `m`; default unit is `s`.
+|===
+
+
+An administrator can clear the auth cache to force the re-querying of authentication and authorization information from the federated auth provider system.
+Use Neo4j Browser or Neo4j Cypher Shell to execute this statement:
+
+[source, cypher]
+----
+CALL dbms.security.clearAuthCache()
+----
+
+[[auth-ldap-ad-encrypted]]
+== Available methods of encryption
+
+Specifying the `xref:reference/configuration-settings.adoc#config_dbms.security.ldap.host[dbms.security.ldap.host]` parameter configures using LDAP without encryption.
+Not specifying the protocol or port results in `ldap` being used over the default port `389`.
+
+[source, properties]
+----
+dbms.security.ldap.host=myactivedirectory.example.com
+dbms.security.ldap.host=myactivedirectory.example.com:389
+dbms.security.ldap.host=ldap://myactivedirectory.example.com
+dbms.security.ldap.host=ldap://myactivedirectory.example.com:389
+----
+
+
+[[auth-ldap-encrypted-starttls]]
+=== Use LDAP with encryption via StartTLS
+
+To configure Active Directory with encryption via StartTLS, set the following parameters:
+
+[source, properties]
+----
+dbms.security.ldap.use_starttls=true
+dbms.security.ldap.host=ldap://myactivedirectory.example.com
+----
+
+[[auth-ldap-encrypted-ldaps]]
+=== Use LDAP with encrypted LDAPS
+
+To configure Active Directory with encrypted LDAPS, set `xref:reference/configuration-settings.adoc#config_dbms.security.ldap.host[dbms.security.ldap.host]` to one of the following.
+If you do not specify the port, the default one `636` is used.
+
+[source, properties]
+----
+dbms.security.ldap.host=ldaps://myactivedirectory.example.com
+dbms.security.ldap.host=ldaps://myactivedirectory.example.com:636
+----
+
+[[auth-ldap-self-signed-certificate]]
+== Use a self-signed certificate (SSL) in a test environment
+
+Production environments should always use an SSL certificate issued by a Certificate Authority for secure access to the LDAP server.
+However, there are scenarios, for example in test environments, where you may want to use an SSL certificate on the LDAP server.
+
+To configure an SSL certificate on LDAP server, enter the details of the certificate using `dbms.jvm.additional` in _neo4j.conf_.
+The path to the certificate file `MyCert.jks` is an absolute path to the Neo4j server.
+
+[source, properties]
+----
+dbms.jvm.additional=-Djavax.net.ssl.keyStore=/path/to/MyCert.jks
+dbms.jvm.additional=-Djavax.net.ssl.keyStorePassword=mypasword
+dbms.jvm.additional=-Djavax.net.ssl.trustStore=/path/to/MyCert.jks
+dbms.jvm.additional=-Djavax.net.ssl.trustStorePassword=mypasword
+----
diff --git a/modules/ROOT/pages/authentication-authorization/manage-execute-permissions.adoc b/modules/ROOT/pages/authentication-authorization/manage-execute-permissions.adoc
new file mode 100644
index 000000000..10823e90a
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/manage-execute-permissions.adoc
@@ -0,0 +1,184 @@
+[role=enterprise-edition]
+[[auth-manage-execute-permissions]]
+= Manage procedure and user-defined function permissions
+:description: This section describes how access control works with procedures and user-defined functions in Neo4j.
+
+
+[[auth-manage-execute-permissions-introduction]]
+== Introduction
+
+To be able to run a procedure or user-defined function, the user needs to have the corresponding execute privilege.
+Procedures and user-defined functions are executed according to the same security rules as regular Cypher statements,
+e.g. a procedure performing writes will fail if called by a user that only has _read_ privileges.
+
+Procedures and user-defined functions can also be run with privileges exceeding the users own privileges.
+This is called _execution boosting_.
+The elevated privileges only apply within the procedure or user-defined function; any operation performed outside will still use the users original privileges.
+
+[NOTE]
+--
+The steps below assume that the procedure or user-defined function is already developed and installed.
+
+Please refer to link:/docs/java-reference/4.4/extending-neo4j#extending-neo4j[Java Reference -> Extending Neo4j] for a description on creating and using user-defined procedures and functions.
+--
+
+
+[[auth-manage-procedure-permissions]]
+== Manage procedure permissions
+
+Procedure permissions can be managed using the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-dbms-administration-execute[native execute privileges].
+These control whether the user is allowed to both execute a procedure, and which set of privileges apply during the execution.
+
+A procedure may be run using the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-execute-procedure[`EXECUTE PROCEDURE` privilege].
+
+This allows the user to execute procedures that match the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-name-globbing[globbed procedures].
+
+.Grant privilege to execute procedure
+====
+[source, cypher]
+----
+GRANT EXECUTE PROCEDURE db.schema.visualization ON DBMS TO visualizer
+----
+
+This will allow any user with the `visualizer` role to execute the `db.schema.visualization`.
+E.g. a user that also have the following privileges:
+
+[source, cypher]
+----
+GRANT TRAVERSE ON GRAPH * NODES A, B TO role
+GRANT TRAVERSE ON GRAPH * RELATIONSHIP R1 TO role
+----
+
+When calling the `db.schema.visualization` procedure that user will only see the `A` and `B` nodes and `R1` relationships, even though there might exist other nodes and relationships.
+====
+
+A procedure may also be executed with elevated privileges using the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-execute-boosted-procedure[`EXECUTE BOOSTED PROCEDURE` privilege].
+
+This allows the user to successfully execute procedures that would otherwise fail during execution with their assigned roles.
+The user is given full privileges for the procedure, during the execution of the procedure only.
+
+.Grant privilege to execute procedure with elevated privileges
+====
+[source, cypher]
+----
+GRANT EXECUTE BOOSTED PROCEDURE db.schema.visualization ON DBMS TO visualizer
+----
+
+This will allow any user with the `visualizer` role to execute the `db.schema.visualization` with elevated privileges.
+When calling the `db.schema.visualization` procedure that user will see all nodes and relationships that exist in the graph, even though they have no traversal privileges.
+====
+
+
+[[auth-manage-function-permissions]]
+== Manage user-defined function permissions
+
+User-defined function permissions can be managed using the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-dbms-administration-execute[native execute privileges].
+These control if the user is both allowed to execute a user-defined function, and which set of privileges apply during the execution.
+
+A user-defined function may be executed using the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-execute-user-defined-function[`EXECUTE USER DEFINED FUNCTION` privilege].
+
+This allows the user to execute user-defined functions that match the link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-name-globbing[globbed user-defined function].
+
+.Grant privilege to execute user-defined function
+====
+[source, cypher]
+----
+GRANT EXECUTE USER DEFINED FUNCTION apoc.any.properties ON DBMS TO custom
+----
+
+This will allow any user with the `custom` role to execute the `apoc.any.properties`.
+E.g. a user that also have the following privilege:
+
+[source, cypher]
+----
+GRANT MATCH {visibleProp} ON GRAPH * NODES A TO role
+----
+
+When calling the user-defined function `MATCH (a:A) RETURN apoc.any.properties(a) AS properties`, they will only see the `visibleProp` even though there might exist other properties.
+====
+
+A user-defined function may also be executed with elevated privileges using the
+link:/docs/cypher-manual/4.4/access-control/dbms-administration#access-control-execute-boosted-user-defined-function[`EXECUTE BOOSTED USER DEFINED FUNCTION` privilege].
+
+This allows the user to successfully execute user-defined functions that would otherwise fail during execution with their assigned roles.
+The user is given full privileges for the user-defined function, during the execution of the function only.
+
+.Grant privilege to execute user-defined function with elevated privileges
+====
+[source, cypher]
+----
+GRANT EXECUTE BOOSTED USER DEFINED FUNCTION apoc.any.properties ON DBMS TO custom
+----
+
+This will allow any user with the `custom` role to execute the `apoc.any.properties` with elevated privileges.
+E.g. a user that also have the following privileges:
+
+[source, cypher]
+----
+GRANT TRAVERSE ON GRAPH * NODES A TO role
+----
+
+When calling the user-defined function `MATCH (a:A) RETURN apoc.any.properties(a) AS properties`, they will see all properties that exist on the matched nodes even though they have no read privileges.
+====
+
+
+[role=deprecated]
+[[auth-manage-execute-permissions-config]]
+== Manage procedure and user-defined function permissions from config setting
+
+It is possible to grant boosting for procedures and user-defined functions through config settings.
+These settings will be translated to temporary `execute boosted procedure` and `execute boosted function` privileges that cannot be revoked.
+
+*`xref:reference/configuration-settings.adoc#config_dbms.security.procedures.default_allowed[dbms.security.procedures.default_allowed]`*::
+
+The setting `dbms.security.procedures.default_allowed` defines a single role that is allowed to execute any procedure or user-defined function
+that is not matched by the `dbms.security.procedures.roles` configuration.
++
+.Configure a default role that can execute procedures and user-defined functions
+====
+
+Assume that we have the following configuration:
+
+[source, properties]
+----
+dbms.security.procedures.default_allowed=superAdmin
+----
+
+This will create the following temporary privileges:
+
+* `GRANT EXECUTE BOOSTED PROCEDURE * ON DBMS TO superAdmin`
+* `GRANT EXECUTE BOOSTED USER DEFINED FUNCTION * ON DBMS TO superAdmin`
+* If the setting dbms.security.procedures.roles has some roles to name defined,
+ then for any procedure/function not also granted to the superAdmin role, create temporary privileges:
+** `DENY EXECUTE BOOSTED PROCEDURE name ON DBMS TO superAdmin`
+** `DENY EXECUTE BOOSTED USER DEFINED FUNCTION name ON DBMS TO superAdmin`
+
+====
++
+
+*`xref:reference/configuration-settings.adoc#config_dbms.security.procedures.roles[dbms.security.procedures.roles]`*::
+
+The `dbms.security.procedures.roles` setting provides fine-grained control over procedures and user-defined functions.
++
+.Configure roles for the execution of specific procedures and user-defined functions
+====
+
+Assume that we have the following configuration:
+
+[source, properties]
+----
+dbms.security.procedures.default_allowed=superAdmin
+dbms.security.procedures.roles=apoc.coll.*:Collector;apoc.trigger.add:TriggerHappy,superAdmin
+----
+
+This will have create the following temporary privileges:
+
+* `GRANT EXECUTE BOOSTED PROCEDURE apoc.coll.* ON DBMS TO Collector`
+* `GRANT EXECUTE BOOSTED USER DEFINED FUNCTION apoc.coll.* ON DBMS TO Collector`
+* `GRANT EXECUTE BOOSTED PROCEDURE apoc.trigger.add ON DBMS TO TriggerHappy, superAdmin`
+* `GRANT EXECUTE BOOSTED USER DEFINED FUNCTION apoc.trigger.add ON DBMS TO TriggerHappy, superAdmin`
+* `GRANT EXECUTE BOOSTED PROCEDURE * ON DBMS TO superAdmin`
+* `GRANT EXECUTE BOOSTED USER DEFINED FUNCTION * ON DBMS TO superAdmin`
+* `DENY EXECUTE BOOSTED PROCEDURE apoc.coll.* ON DBMS TO superAdmin`
+* `DENY EXECUTE BOOSTED USER DEFINED FUNCTION apoc.coll.* ON DBMS TO superAdmin`
+====
diff --git a/modules/ROOT/pages/authentication-authorization/sso-integration.adoc b/modules/ROOT/pages/authentication-authorization/sso-integration.adoc
new file mode 100644
index 000000000..700b72d9a
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/sso-integration.adoc
@@ -0,0 +1,276 @@
+[role=enterprise-edition]
+[[auth-sso-integration]]
+= Integration with Single Sign-On Services
+:description: This section describes Neo4j support for integrating with SSO identity providers using OpenID Connect. For examples with different providers and troubleshooting, see the xref:tutorial/tutorial-sso-configuration.adoc[SSO configuration tutorial].
+
+[[auth-sso-introduction]]
+== Introduction
+
+Neo4j supports OpenID Connect (OIDC), which allows for integration with many identity providers including Okta, Microsoft Azure Active Directory, and Google.
+This integration permits federated users, managed by the identity provider, to access Neo4j instead of, or in addition to the native users and roles.
+
+[NOTE]
+====
+Currently it is not possible to login to Cypher Shell using SSO authentication and authorization.
+====
+
+[[auth-sso-parameters]]
+== OIDC configuration settings
+
+Neo4j supports multiple OIDC identity providers at the same time, as such each provider configuration must be assigned a prefix to differentiate it from others.
+In the configuration examples below the provider-specific prefix is represented by ``, which should be replaced with a name representing your provider.
+For example, if you are using Okta as your identity provider you might use `okta` in the place of `` below.
+
+The following configuration settings are important to consider when configuring single sign-on.
+For a more detailed overview of the single sign-on configuration options, see xref:reference/configuration-settings.adoc[Configuration settings].
+These settings can also be updated while the database is running, see xref:configuration/dynamic-settings.adoc[Dynamic settings] for more information on how to do this.
+Altering any of these settings causes users to re-authenticate as their permissions may have changed as a result.
+
+[options="header",cols="<3,<1,<3"]
+|===
+| Parameter name
+| Default value
+| Description
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.display_name[dbms.security.oidc..display_name]
+|
+| The display name for the provider.
+This is displayed in clients such as Neo4j Browser and Bloom.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.auth_flow[dbms.security.oidc..auth_flow]
+| pkce
+| The OIDC auth_flow for clients such as Neo4j Browser and Bloom to use.
+Supported values are `pkce` and `implicit`.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.well_known_discovery_uri[dbms.security.oidc..well_known_discovery_uri]
+|
+| The OpenID Connect Discovery URL for the provider.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.auth_endpoint[dbms.security.oidc..auth_endpoint]
+|
+| URL of the provider's Authorization Endpoint.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.auth_params[dbms.security.oidc..auth_params]
+|
+| Optional parameters that clients may require with the Authorization Endpoint. The map is a semicolon-separated list of key-value pairs. For example: k1=v1;k2=v2.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.token_endpoint[dbms.security.oidc..token_endpoint]
+|
+| URL of the provider's OAuth 2.0 Token Endpoint.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.token_params[dbms.security.oidc..token_params]
+|
+| Option parameters that clients may require with the Token Endpoint. The map is a semicolon-separated list of key-value pairs. For example: k1=v1;k2=v2.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.jwks_uri[dbms.security.oidc..jwks_uri]
+|
+| URL of the provider's JSON Web Key Set.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.user_info_uri[dbms.security.oidc..user_info_uri]
+|
+| URL of the provider's UserInfo Endpoint.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.issuer[dbms.security.oidc..issuer]
+|
+| URL that the provider asserts as its issuer identifier.
+This will be checked against the `iss` claim in the token.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.audience[dbms.security.oidc..audience]
+|
+| The expected value for the `aud` claim.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.client_id[dbms.security.oidc..client_id]
+|
+| The `client_id` of this client as issued by the provider.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.params[dbms.security.oidc..params]
+|
+| Option parameters that clients may require. The map is a semicolon-separated list of key-value pairs. For example: k1=v1;k2=v2.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.config[dbms.security.oidc..config]
+|
+| Option additional configuration that clients may require. The map is a semicolon-separated list of key-value pairs. For example: k1=v1;k2=v2.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.get_groups_from_user_info[dbms.security.oidc..get_groups_from_user_info]
+| false
+| Whether to fetch the groups claim from the user info endpoint on the identity provider.
+The default is `false`, to read the claim from the token.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.get_username_from_user_info[dbms.security.oidc..get_username_from_user_info]
+| false
+| Whether to fetch the username claim from the user info endpoint on the identity provider.
+The default is `false`, to read the claim from the token.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.claims.username[dbms.security.oidc..claims.username]
+| sub
+| The claim to use for the database username.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.claims.groups[dbms.security.oidc..claims.groups]
+|
+| The claim to use for the database roles.
+
+| xref:reference/configuration-settings.adoc#config_dbms.security.oidc.-provider-.authorization.group_to_role_mapping[dbms.security.oidc..authorization.group_to_role_mapping]
+|
+| List an authorization mapping from groups to the pre-defined built-in roles `admin`, `architect`, `publisher`, `editor`, and `reader`, or to any custom-defined roles.
+|===
+
+[[auth-sso-configure-sso]]
+== Configure Neo4j to use OpenID Connect
+
+First, you configure Neo4j to use OpenID Connect as an authentication and authorization provider.
+
+. Uncomment the setting `dbms.security.auth_enabled=false` and change its value to `true` to enable the security feature.
+. Uncomment the settings `dbms.security.authentication_providers` and `dbms.security.authorization_providers` and change their value to `oidc-`, where `` maps to the provider name used in the configuration settings.
+This way, the OIDC connector is used as a security provider for both authentication and authorization.
+These configuration values are comma-separated lists, so if you wish to continue to use native authentication and authorization alongside SSO, then these providers can be added to the existing `native` provider:
++
+.Configuration
+======
+[source,configuration,role="noheader"]
+----
+dbms.security.authentication_providers=oidc-newsso,oidc-oldsso,native
+dbms.security.authorization_providers=oidc-newsso,oidc-oldsso,native
+----
+This example has two OpenID Connect providers configured, as well as Neo4j native authorization and authentication.
+======
+
+[[auth-sso-map-idp-roles]]
+== Map the Identity Provider Groups to the Neo4j Roles
+
+Before identity provider managed groups can be used with Neo4j, you have to decide on an approach for mapping identity provider groups to Neo4j roles.
+The simplest approach is to create identity provider groups with the same names as Neo4j roles.
+If you decide to go this way, no mapping configuration is necessary.
+Assuming, however, that identity provider groups do not directly map 1:1 to the desired Neo4j roles, it is necessary to map the identity provider groups to the xref:authentication-authorization/built-in-roles.adoc[Neo4j built-in] and custom-defined roles.
+To do that, you need to know what privileges the Neo4j roles have, and based on these privileges, create the mapping to the groups defined in the identity provider.
+The map must be formatted as a semicolon-separated list of key-value pairs, where the key is a comma-separated list of the identity provider group names and the value is a comma-separated list of the corresponding role names.
+For example, `group1=role1;group2=role2;group3=role3,role4,role5;group4,group5=role6`.
+
+.Example of identity provider groups to Neo4j roles mapping
+====
+[source, role=noheader]
+----
+dbms.security.oidc.mysso.authorization.group_to_role_mapping=\
+ neo4j_readonly = reader; \ #<1>
+ neo4j_rw = editor,publisher; \ #<2>
+ neo4j_rw,neo4j_create = publisher; \ #<3>
+ neo4j_create,neo4j_schema = architect; \
+ neo4j_dba = admin; \
+ neo4j_exec = rolename #<4>
+----
+
+<1> Mapping of an identity provider group to a Neo4j built-in role.
+<2> Mapping of an identity provider group to two Neo4j built-in roles.
+<3> Mapping of two identity provider groups to a Neo4j built-in role.
+<4> Mapping of an identity provider group to a custom-defined role.
+Custom-defined roles, such as `rolename`, must be explicitly created using the `CREATE ROLE rolename` command before they can be used to grant privileges.
+See link:/docs/cypher-manual/4.4/access-control/manage-users[the Cypher Manual -> Creating roles].
+====
+
+[[auth-sso-configure-provider]]
+== Configure Neo4j to use an OpenID Connect Identity Provider
+
+This option allows users to log in through an OIDC compliant identity provider by offering a token from the provider instead of a username and password.
+Typically, these tokens take the form of a signed JSON Web Token (JWT).
+In the configuration examples below, we are using `mysso` as our provider name.
+It is recommended to use a name describing the provider that is being integrated.
+
+[[auth-sso-configure-provider-jwt]]
+=== OpenID Connect Using JWT Claims
+
+In this configuration, Neo4j receives a JWT from the identity provider containing claims representing the database username (e.g. email), and the Neo4j roles.
+
+. Set a Display Name
++
+In the _neo4j.conf_ file, uncomment and configure the following settings:
++
+[source, properties]
+----
+dbms.security.oidc.mysso.display_name=SSO Provider
+----
+This is displayed on a button on the login page of clients such as Neo4j Browser and Bloom, so that users can identify the provider they are using to login.
+
+. Configure Discovery:
++
+Uncomment and configure the following settings:
++
+[source, properties]
+----
+dbms.security.oidc.mysso.well_known_discovery_uri=https://my-idp.example.com/.well-known/openid-configuration
+----
+The `well_known_discovery` endpoint of the identity provider supplies the OpenID Provider Metadata to allow Neo4j to interact with a provider.
+It is also possible to configure the provider settings manually:
++
+[source, properties]
+----
+dbms.security.oidc.mysso.auth_endpoint=https://my-idp.example.com/openid-connect/auth
+dbms.security.oidc.mysso.token_endpoint=https://my-idp.example.com/openid-connect/token
+dbms.security.oidc.mysso.jwks_uri=https://my-idp.example.com/openid-connect/certs
+dbms.security.oidc.mysso.user_info_uri=https://my-idp.example.com/openid-connect/userinfo
+dbms.security.oidc.mysso.issuer=abcd1234
+----
+Manual settings always take priority over those retrieved from the discovery endpoint.
+
+. Configure Audience:
++
+Provide the expected value for the audience(`aud`) claim:
++
+[source, properties]
+----
+dbms.security.oidc.mysso.claims.audience=myaudience
+----
+In some situations there may be multiple values for the `aud` claim.
+In this situation, the id_token should contain an authorized party(`azp`) claim containing the client id, which is configured as follows:
++
+[source, properties]
+----
+dbms.security.oidc.mysso.claims.client_id=myclientid
+----
+
+. Configure Claims:
++
+Provide the name of the claims that map to the database username and roles.
+`username` is expected to be a string claim and `roles` is expected to be a list of strings.
++
+[source, properties]
+----
+dbms.security.oidc.mysso.claims.username=sub
+dbms.security.oidc.mysso.claims.groups=roles
+----
+
+. Optionally, map the groups in the OIDC groups claim to the Neo4j built-in and custom roles.
+See xref:authentication-authorization/sso-integration.adoc#auth-sso-map-idp-roles[Map the Identity Provider Groups to the Neo4j Roles].
+
+[[auth-sso-configure-provider-userinfo]]
+=== OpenID Connect Fetching Claims from Provider
+
+In this configuration, Neo4j receives a token from the identity provider and uses that token to call back to the identity provider using its UserInfo endpoint to retrieve claims for the database username and Neo4j roles.
+
+. Configure as for JWT Claims.
++
+Configure Neo4j for xref:authentication-authorization/sso-integration.adoc#auth-sso-configure-provider-jwt[OpenID Connect Using JWT Claims].
+
+. Configure the claims to fetch from the UserInfo endpoint:
++
+[source, properties]
+----
+dbms.security.oidc.mysso.get_username_from_user_info=true
+dbms.security.oidc.mysso.get_groups_from_user_info=true
+----
+It is possible to fetch just the username, just the groups, or both from the userinfo endpoint.
+
+[[auth-sso-self-signed-certificate]]
+== Use a self-signed certificate (SSL) in a test environment
+
+Production environments should always use an SSL certificate issued by a Certificate Authority for secure access to the identity provider.
+However, there are scenarios, for example in test environments, where you may want to use a self-signed SSL certificate on the identity provider server.
+
+To configure a self-signed SSL certificate used on an identity provider server, enter the details of a Java keystore containing the relevant certificates using `dbms.jvm.additional` in _neo4j.conf_.
+The path to the certificate file `MyCert.jks` is an absolute path to the Neo4j server.
+
+[source, properties]
+----
+dbms.jvm.additional=-Djavax.net.ssl.keyStore=/path/to/MyCert.jks
+dbms.jvm.additional=-Djavax.net.ssl.keyStorePassword=mypasword
+dbms.jvm.additional=-Djavax.net.ssl.trustStore=/path/to/MyCert.jks
+dbms.jvm.additional=-Djavax.net.ssl.trustStorePassword=mypasword
+----
diff --git a/modules/ROOT/pages/authentication-authorization/terminology.adoc b/modules/ROOT/pages/authentication-authorization/terminology.adoc
new file mode 100644
index 000000000..9b8da028a
--- /dev/null
+++ b/modules/ROOT/pages/authentication-authorization/terminology.adoc
@@ -0,0 +1,33 @@
+[role=enterprise-edition]
+[[auth-terminology]]
+= Terminology
+:description: This section lists the relevant terminology related to authentication and authorization in Neo4j.
+
+The following terms are relevant to role-based access control within Neo4j:
+
+[.compact]
+[[term-active-user]]active user::
+A user who is active within the system and can perform actions prescribed by any assigned roles on the data.
+This is in contrast to a suspended user.
+
+[[term-administrator]]administrator::
+This is a user who has been assigned the admin role.
+
+[[term-current-user]]current user::
+This is the currently logged-in user invoking the commands described in this chapter.
+
+[[term-password-policy]]password policy::
+The password policy is a set of rules of what makes up a valid password.
+For Neo4j, the following rules apply:
+* The password cannot be the empty string.
+* When changing passwords, the new password cannot be the same as the previous password.
+
+[[term-role]]role::
+This is a collection of actions -- such as read and write -- permitted on the data.
+
+[[term-suspended-user]]suspended user::
+A user who has been suspended is not able to access the database in any capacity, regardless of any assigned roles.
+
+[[term-user]]user::
+* A user is composed of a username and credentials, where the latter is a unit of information, such as a password, verifying the identity of a user.
+* A user may represent a human, an application etc.
diff --git a/modules/ROOT/pages/backup-restore/copy-database.adoc b/modules/ROOT/pages/backup-restore/copy-database.adoc
new file mode 100644
index 000000000..f049720e9
--- /dev/null
+++ b/modules/ROOT/pages/backup-restore/copy-database.adoc
@@ -0,0 +1,282 @@
+[role=enterprise-edition]
+[[copy-database]]
+= Copy a database store
+:description: This section describes how to copy the data store of an existing offline database to a new database.
+
+A user database or backup can be copied to a Neo4j instance using the `copy` command of `neo4j-admin`.
+
+[NOTE]
+====
+`neo4j-admin copy` is not supported for use on the `system` database.
+
+In Fabric deployments, `neo4j-admin copy` cannot be applied to the xref:fabric/introduction.adoc#fabric-fabric-concepts[Fabric virtual database].
+It must be run directly on the databases that are part of the Fabric setup.
+====
+
+
+[WARNING]
+====
+It is important to note that `neo4j-admin copy` is an IOPS-intensive process.
+Using this process for upgrading or migration purposes can have significant performance implications, depending on your disc specification.
+It is therefore not appropriate for all use cases.
+
+
+Estimating the processing time::
++
+--
+Estimations for how long the `neo4j-admin copy` command will take can be made based upon the following:
+
+* Neo4j, like many other databases, do IO in 8K pages.
+* Your disc manufacturer will have a value for the maximum IOPS it can process.
+
+For example, if your disc manufacturer has provided a maximum of 5000 IOPS, you can reasonably expect up to 5000 such page operations a second.
+Therefore, the maximal theoretical throughput you can expect is 40MB/s (or 144 GB/hour) on that disc.
+You may then assume that the best-case scenario for running `neo4j-admin copy` on that 5000 IOPS disc is that it will take at least 1 hour to process a 144 GB database. footnote:[The calculations are based on `MB/s = (IOPS * B) ÷ 10^6`,
+where `B` is the block size in bytes; in the case of Neo4j, this is `8000`. GB/hour can then be calculated from `(MB/s * 3600) ÷ 1000`.]
+
+However, it is important to remember that the process must read 144 GB from the source database, and must also write to the target store (assuming the target store is of comparable size).
+Additionally, there are internal processes during the copy that will read/modify/write the store multiple times.
+Therefore, with an additional 144 GB of both read and write, the best-case scenario for running `neo4j-admin copy` on a 5000 IOPS disc is that it will take *at least 3 hours to process a 144 GB database*.
+
+Finally, it is also important to consider that in almost all Cloud environments, the published IOPS value may not be the same as the actual value, or be able to continuously maintain the maximum possible IOPS.
+The real processing time for this example _could_ be well above that estimation of 3 hours.
+--
+
+For detailed information about supported methods of upgrade and migration, see the https://neo4j.com/docs/upgrade-migration-guide/current/[Neo4j Upgrade and Migration Guide].
+====
+
+[[copy-database-command]]
+== Command
+
+`neo4j-admin copy` copies the _data store_ of an existing **offline** database to a new database.
+
+[[copy-database-usage]]
+=== Usage
+
+The `neo4j-admin copy` command can be used to clean up database inconsistencies, compact stores, and do a direct migration from Neo4j 3.5 to any 4.x version.
+It can process an optional set of filters, which you can use to remove any unwanted data before copying the database.
+The command also reclaims the unused space of a database and creates a defragmented copy of that database or backup in the destination Neo4j instance.
+
+[NOTE]
+====
+`neo4j-admin copy` copies the _data store_ without the _schema_ (indexes and constraints).
+However, if the database has a schema defined, the command will output Cypher statements, which you can run to recreate the indexes and constraints.
+====
+
+[TIP]
+====
+For a detailed example of how to reclaim unused space, see xref:performance/space-reuse.adoc#space-reuse-reclaim-space[Reclaim unused space]. +
+For a detailed example of how to back up a 3.5 database and use the `neo4j-admin copy` command to compact its store and migrate it to a 4.x Neo4j standalone instance, see link:{neo4j-docs-base-uri}/upgrade-migration-guide/migration/migrate-to-4.any/online-backup-copy-database/[Upgrade and Migration Guide -> Tutorial: Back up and copy a database in a standalone instance].
+====
+
+[WARNING]
+====
+`neo4j-admin copy` preserves the node IDs; however, the relationships get new IDs.
+====
+
+[[copy-database-syntax]]
+=== Syntax
+
+[source,role=noheader]
+----
+neo4j-admin copy [--verbose]
+ [--from-database=]
+ [--from-path=]
+ [--from-path-tx=]
+ --to-database=
+ [--neo4j-home-directory=]
+ [--force]
+ [--compact-node-store]
+ [--to-format=]
+ [--delete-nodes-with-labels=