From 4e9876e45b44c04eed6e2f947efd0197b1bc77e6 Mon Sep 17 00:00:00 2001 From: Stefano Ottolenghi Date: Tue, 29 Oct 2024 07:07:54 +0100 Subject: [PATCH] go --- .../modules/ROOT/pages/connect-advanced.adoc | 73 ++++++++++++++++++ .../modules/ROOT/pages/connect-advanced.adoc | 74 +++++++++++++++++-- 2 files changed, 142 insertions(+), 5 deletions(-) diff --git a/go-manual/modules/ROOT/pages/connect-advanced.adoc b/go-manual/modules/ROOT/pages/connect-advanced.adoc index a12b3dcb..e1f7f839 100644 --- a/go-manual/modules/ROOT/pages/connect-advanced.adoc +++ b/go-manual/modules/ROOT/pages/connect-advanced.adoc @@ -64,6 +64,79 @@ driver, err := neo4j.NewDriverWithContext(dbUri, neo4j.NoAuth()) ---- +[role=label--new-5.27] +== Mutual TLS (client-side certificates as 2FA) + +Mutual TLS (mTLS) allows you to use a client certificate as second factor for authenticating with the server. +The certificate can only be used together with an authentication token and is not a replacement of regular authentication, unless authentication is disabled on the server. + +[.tabbed-example] +===== +[.include-with-static-certificate] +====== +Use link:https://pkg.go.dev/github.com/neo4j/neo4j-go-driver/v5/neo4j/auth#NewStaticClientCertificateProvider[`auth.NewStaticClientCertificateProvider()`] for static certificates. + +The method takes a link:https://pkg.go.dev/github.com/neo4j/neo4j-go-driver/v5/neo4j/auth#ClientCertificate[`ClientCertificate`] instance. + +[source, go, test-skip] +---- +password := "theCertPassword" +certProvider, err := auth.NewStaticClientCertificateProvider(auth.ClientCertificate { + CertFile: "path/to/cert.pem", + KeyFile: "path/to/key.pem", + Password: &password, +}) +if err != nil { + log.Fatalf("Failed to load certificate: %v", err) +} +_, _ = neo4j.NewDriverWithContext(dbUri, neo4j.BasicAuth(dbUser, dbPassword, ""), func(config *config.Config) { + config.ClientCertificateProvider = certProvider +}) +---- + +====== +[.include-with-rotating-certificate] +====== + +Use link:https://pkg.go.dev/github.com/neo4j/neo4j-go-driver/v5/neo4j/auth#NewRotatingClientCertificateProvider[`auth.NewRotatingClientCertificateProvider()`] for rotating certificates. + +The method takes a link:https://pkg.go.dev/github.com/neo4j/neo4j-go-driver/v5/neo4j/auth#ClientCertificate[`ClientCertificate`] instance. + +[source, go, test-skip] +---- +password := "theCertPassword" +certProvider, err := auth.NewRotatingClientCertificateProvider(auth.ClientCertificate { + CertFile: "path/to/cert.pem", + KeyFile: "path/to/key.pem", + Password: &password, +}) +if err != nil { + log.Fatalf("Failed to load certificate: %v", err) +} +_, _ = neo4j.NewDriverWithContext(dbUri, neo4j.BasicAuth(dbUser, dbPassword, ""), func(config *config.Config) { + config.ClientCertificateProvider = certProvider +}) + +// use the driver a bit... + +// when it's time to rotate the certificate... +err = provider.UpdateCertificate(auth.ClientCertificate { + CertFile: "path/to/new_cert.pem", + KeyFile: "path/to/new_key.pem", + Password: &password, +}) +if err != nil { + log.Fatalf("Failed to update certificate: %v", err) +} + +// use the driver again... +---- + +====== +===== + + +For more information, see link:https://pkg.go.dev/github.com/neo4j/neo4j-go-driver/v5/neo4j/auth#ClientCertificateProvider[API docs -> `ClientCertificateProvider`]. + + == Custom address resolver When creating a `DriverWithContext` object, you can specify a _resolver_ function to resolve the connection address the driver is initialized with. diff --git a/python-manual/modules/ROOT/pages/connect-advanced.adoc b/python-manual/modules/ROOT/pages/connect-advanced.adoc index 7e032fd9..c6129b76 100644 --- a/python-manual/modules/ROOT/pages/connect-advanced.adoc +++ b/python-manual/modules/ROOT/pages/connect-advanced.adoc @@ -63,17 +63,25 @@ Use the function link:{neo4j-docs-base-uri}/api/python-driver/current/api.html#n If authentication is disabled on the server, the authentication parameter can be omitted entirely. +[role=label--new-5.27] == Mutual TLS (client-side certificates as 2FA) Mutual TLS (mTLS) allows you to use a client certificate as second factor for authenticating with the server. The certificate can only be used together with an authentication token and is not a replacement of regular authentication, unless authentication is disabled on the server. +[.tabbed-example] +===== +[.include-with-static-certificate] +====== +Use link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.auth_management.ClientCertificateProviders.static[`ClientCertificateProviders.static()`] for static certificates. + +The method takes a link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.auth_management.ClientCertificate[`ClientCertificate`] instance. + [source, python, test-skip] ---- import neo4j from neo4j.auth_management import ( - ClientCertificateProviders, ClientCertificate, + ClientCertificateProviders, ) @@ -98,12 +106,68 @@ with neo4j.GraphDatabase.driver( auth=AUTH, client_certificate=cert_provider, ) as driver: - with driver.session() as session: - result = session.run("RETURN 'now with mTLS 🔒'") - for record in result: - print(record) + ... +---- + +====== +[.include-with-rotating-certificate] +====== + +Use link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.auth_management.ClientCertificateProviders.rotating[`ClientCertificateProviders.rotating()`] for rotating certificates. + +The method takes a link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.auth_management.ClientCertificate[`ClientCertificate`] instance. + +[source, python, test-skip] +---- +import neo4j +from neo4j.auth_management import ( + ClientCertificate, + ClientCertificateProviders, +) + +# must use a secure driver with client certificates (...+s[sc] scheme or encrypted=True) +# ex. "neo4j+s://example.com:7687" +URI = "" +# auth still required, unless server has authentication disabled +AUTH = ("", "") + + +cert_provider = ClientCertificateProviders.rotating( + ClientCertificate( + # path to public certificate to load + "path/to/cert.pem", + # path to private key to load + "path/to/key.pem", + # password to decrypt private key (can be a function or string) + # see also Python's ssl.SSLContext.load_cert_chain() + lambda: "password", + ) +) +driver = neo4j.GraphDatabase.driver( + URI + auth=(USERNAME, PASSWORD), + client_certificate=cert_provider +) + +# do work with the driver, until the certificate needs to be rotated +# ... + +cert_provider.update_certificate( + ClientCertificate( + certfile="path/to/new/certfile.pem", + keyfile="path/to/new/keyfile.pem", + password=lambda: "new_super_secret_password" + ) +) + +# do more work with the driver, until the certificate needs to be +# rotated again +# ... ---- +====== +===== + + For more information, see link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.auth_management.ClientCertificateProvider[API docs -> `ClientCertificateProvider`].