From 490fafb3bbc67f82b402630ed1ad0beb5024b918 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:59:11 -0500 Subject: [PATCH 1/6] wip --- source/fundamentals/authentication.txt | 1 + .../authentication/enterprise-mechanisms.txt | 160 +++++++++++++++++- 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/source/fundamentals/authentication.txt b/source/fundamentals/authentication.txt index fe07df164..de0fc31b0 100644 --- a/source/fundamentals/authentication.txt +++ b/source/fundamentals/authentication.txt @@ -35,6 +35,7 @@ Enterprise Edition which includes: - ``Kerberos (GSSAPI/SSPI)`` - ``LDAP (PLAIN)`` +- ``MONGODB-OIDC`` .. note:: For instructions on MongoDB driver installation and deployment setup, see diff --git a/source/fundamentals/authentication/enterprise-mechanisms.txt b/source/fundamentals/authentication/enterprise-mechanisms.txt index 91e9faade..bc666b146 100644 --- a/source/fundamentals/authentication/enterprise-mechanisms.txt +++ b/source/fundamentals/authentication/enterprise-mechanisms.txt @@ -10,9 +10,16 @@ Enterprise Authentication Mechanisms :depth: 1 :class: singlecol +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ldap, encryption, principal, tls + In this guide, you can find sample code for connection to MongoDB with each authentication mechanism available in the MongoDB Enterprise Edition: -``Kerberos (GSSAPI/SSPI)`` and ``LDAP (PLAIN)``. +``Kerberos (GSSAPI/SSPI)``, ``LDAP (PLAIN)``, and ``MONGODB-OIDC``. ``Kerberos (GSSAPI/SSPI)`` -------------------------- @@ -138,3 +145,154 @@ in the following sample code. The authentication mechanism is named ``PLAIN`` instead of ``LDAP`` since it authenticates using the `PLAIN Simple Authentication and Security Layer (SASL) defined in RFC-4616 `_. + +MONGODB-OIDC +------------ + +.. important:: + + The MONGODB-OIDC authentication mechanism requires {+mdb-server+} v7.0 or later running + on a Linux platform. + +The following sections describe how to use the MONGODB-OIDC authentication mechanism to +authenticate from various platforms. + +For more information about the MONGODB-OIDC authentication mechanism, see +:manual:`OpenID Connect Authentication ` and +:manual:`MongoDB Server Parameters ` +in the {+mdb-server+} manual. + +.. _node-mongodb-oidc-azure-imds: + +Azure IMDS +~~~~~~~~~~ + +If your application runs on an Azure VM, or otherwise uses the +`Azure Instance Metadata Service `__ +(IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s built-in Azure +support. + +The following code example shows how to specify Azure IMDS OIDC authentication. +Replace the ```` placeholder with the +value of the ``audience`` parameter configured on your MongoDB deployment. +Optionally, replace the ```` placeholder with the client ID or application ID of the +Azure managed identity or enterprise application. + +.. code-block:: js + + const client = new MongoClient("mongodb+srv://@:/?" + + "authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=azure"); + +.. _node-mongodb-oidc-gcp-imds: + +GCP IMDS +~~~~~~~~ + +If your application runs on a Google Compute Engine VM, or otherwise uses the +`GCP Instance Metadata Service `__, +you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP +support. + +The following code example shows how to specify GCP IMDS OIDC authentication. +Replace the ```` placeholder with the +value of the ``audience`` parameter configured on your MongoDB deployment. + +.. code-block:: js + + const client = new MongoClient("mongodb+srv://:/?" + + "authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=gcp"); + +Custom Callback +~~~~~~~~~~~~~~~ + +The {+driver-short+} doesn't offer built-in support for all platforms, including +Azure Functions and Azure Kubernetes Service (AKS). Instead, you +must define a custom callback to use OIDC to authenticate from these platforms. + +First, define a custom function with the following signature: + +.. code-block:: js + + const myCallback = (params: OIDCCallbackParams): Promise => { } + +The ``OIDCCallbackParams`` object contains the following properties: + +.. list-table:: + :header-rows: 1 + + * - Property + - Value + * - ``timeoutContext`` + - + + +.. code-block:: js + +const oidcCallBack = (params: OIDCCallbackParams): Promise => { + // params.timeoutContext is an AbortSignal that will abort after 30 seconds for non-human and 5 minutes for human. + // params.version is the current OIDC API version. + // params.idpInfo is the IdP info returned from the server. + // params.username is the optional username. + + // Make a call to get a token. +const token = ...; +return { + accessToken: token, + expiresInSeconds: 300, + refreshToken: token +}; +} + +const client = new MongoClient('mongodb+srv://:/?authMechanism=MONGODB-OIDC', { + authMechanismProperties: { + OIDC_CALLBACK: oidcCallback + } +}); + +contains two methods: + +- ``GetOidcAccessToken()``: This method accepts the parameters to the callback method + and returns the callback response. +- ``GetOidcAccessTokenAsync()``: This method is an asynchronous version of the previous + method. + +The following code is an example implementation of the ``IOidcCallback`` interface. +In this example, the methods retrieve an OIDC token from a file named ``"access-token.dat"`` +in the local file system. + +.. code-block:: csharp + + public class MyCallback : IOidcCallback + { + public OidcAccessToken GetOidcAccessToken( + OidcCallbackParameters parameters, + CancellationToken cancellationToken) + { + var accessToken = File.ReadAllText("access-token.dat"); + return new(accessToken, expiresIn: null); + } + + public async Task GetOidcAccessTokenAsync( + OidcCallbackParameters parameters, + CancellationToken cancellationToken) + { + var accessToken = await File.ReadAllTextAsync( + "access-token.dat", + cancellationToken) + .ConfigureAwait(false); + return new(accessToken, expiresIn: null); + } + } + +After you define a class that contains your custom callback methods, call the +``MongoCredential.CreateOidcCredential()`` method and pass in a new instance of your +class. Store the result of this method call in the ``Credential`` property of your +``MongoClientSettings`` object, as shown in the following code example: + +.. code-block:: csharp + + var mongoClientSettings = MongoClientSettings.FromConnectionString("mongodb://[:port]"); + mongoClientSettings.Credential = MongoCredential.CreateOidcCredential(new MyCallback()); + var client = new MongoClient(mongoClientSettings); From 9949a81edd588314a7e14377396fd17f4a24af3b Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:35:32 -0500 Subject: [PATCH 2/6] first draft --- .../authentication/enterprise-mechanisms.txt | 114 ++++++++---------- 1 file changed, 49 insertions(+), 65 deletions(-) diff --git a/source/fundamentals/authentication/enterprise-mechanisms.txt b/source/fundamentals/authentication/enterprise-mechanisms.txt index bc666b146..a6b6b80e6 100644 --- a/source/fundamentals/authentication/enterprise-mechanisms.txt +++ b/source/fundamentals/authentication/enterprise-mechanisms.txt @@ -211,13 +211,15 @@ The {+driver-short+} doesn't offer built-in support for all platforms, including Azure Functions and Azure Kubernetes Service (AKS). Instead, you must define a custom callback to use OIDC to authenticate from these platforms. -First, define a custom function with the following signature: +First, define a function that retrieves the access token to use for OIDC authentication. +This function must have the following signature: .. code-block:: js const myCallback = (params: OIDCCallbackParams): Promise => { } -The ``OIDCCallbackParams`` object contains the following properties: +The ``OIDCCallbackParams`` parameter contains the following properties, which you can +access inside the function: .. list-table:: :header-rows: 1 @@ -225,74 +227,56 @@ The ``OIDCCallbackParams`` object contains the following properties: * - Property - Value * - ``timeoutContext`` - - + - An ``AbortSignal`` that aborts after 30 seconds + * - ``version`` + - The current OIDC API version + * - ``idpInfo`` + - The IdP information returned from the server + * - ``username`` + - The username included in the connection string, if any + * - ``refreshToken`` + - The refresh token to request a new access token from the issuer, if any + +The callback function must return an ``OIDCResponse`` object. This object contains the +following properties: +.. list-table:: + :header-rows: 1 + + * - Property + - Value + * - ``accessToken`` + - The access token to use for authentication. + * - ``expiresInSeconds`` + - *Optional.* The number of seconds until the access token expires. + * - ``refreshToken`` + - *Optional.* The refresh token to request a new access token from the issuer. + +The following example shows a callback function that retrieves an OIDC access token +from a file named ``access-token.dat`` in the local file system: .. code-block:: js -const oidcCallBack = (params: OIDCCallbackParams): Promise => { - // params.timeoutContext is an AbortSignal that will abort after 30 seconds for non-human and 5 minutes for human. - // params.version is the current OIDC API version. - // params.idpInfo is the IdP info returned from the server. - // params.username is the optional username. - - // Make a call to get a token. -const token = ...; -return { - accessToken: token, - expiresInSeconds: 300, - refreshToken: token -}; -} - -const client = new MongoClient('mongodb+srv://:/?authMechanism=MONGODB-OIDC', { - authMechanismProperties: { - OIDC_CALLBACK: oidcCallback - } -}); - -contains two methods: - -- ``GetOidcAccessToken()``: This method accepts the parameters to the callback method - and returns the callback response. -- ``GetOidcAccessTokenAsync()``: This method is an asynchronous version of the previous - method. - -The following code is an example implementation of the ``IOidcCallback`` interface. -In this example, the methods retrieve an OIDC token from a file named ``"access-token.dat"`` -in the local file system. - -.. code-block:: csharp - - public class MyCallback : IOidcCallback - { - public OidcAccessToken GetOidcAccessToken( - OidcCallbackParameters parameters, - CancellationToken cancellationToken) - { - var accessToken = File.ReadAllText("access-token.dat"); - return new(accessToken, expiresIn: null); - } - - public async Task GetOidcAccessTokenAsync( - OidcCallbackParameters parameters, - CancellationToken cancellationToken) - { - var accessToken = await File.ReadAllTextAsync( - "access-token.dat", - cancellationToken) - .ConfigureAwait(false); - return new(accessToken, expiresIn: null); - } + import fs from "node:fs"; + + const myCallback = (params: OIDCCallbackParams): Promise => { + const token = fs.readFileSync("access-token.dat", "utf8"); + + return { + accessToken: token, + expiresInSeconds: 300, + refreshToken: token + }; } -After you define a class that contains your custom callback methods, call the -``MongoCredential.CreateOidcCredential()`` method and pass in a new instance of your -class. Store the result of this method call in the ``Credential`` property of your -``MongoClientSettings`` object, as shown in the following code example: +After you define your callback function, pass it to the ``MongoClient`` constructor +as part of the ``authMechanismProperties`` parameter, as shown in the following +example: -.. code-block:: csharp +.. code-block:: js - var mongoClientSettings = MongoClientSettings.FromConnectionString("mongodb://[:port]"); - mongoClientSettings.Credential = MongoCredential.CreateOidcCredential(new MyCallback()); - var client = new MongoClient(mongoClientSettings); + const client = new MongoClient("mongodb+srv://:/?authMechanism=MONGODB-OIDC", { + authMechanismProperties: { + OIDC_CALLBACK: oidcCallback + } + }); \ No newline at end of file From ffcfd3cbd3b733566632a7ec803fbddfbd3a03a8 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:17:22 -0500 Subject: [PATCH 3/6] human auth --- .../authentication/enterprise-mechanisms.txt | 95 +++++++++++++++---- 1 file changed, 77 insertions(+), 18 deletions(-) diff --git a/source/fundamentals/authentication/enterprise-mechanisms.txt b/source/fundamentals/authentication/enterprise-mechanisms.txt index a6b6b80e6..b74651cf0 100644 --- a/source/fundamentals/authentication/enterprise-mechanisms.txt +++ b/source/fundamentals/authentication/enterprise-mechanisms.txt @@ -172,17 +172,21 @@ If your application runs on an Azure VM, or otherwise uses the (IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s built-in Azure support. -The following code example shows how to specify Azure IMDS OIDC authentication. +The following code example shows how to specify Azure IMDS OIDC as the authentication +mechanism. Replace the ```` placeholder with the value of the ``audience`` parameter configured on your MongoDB deployment. Optionally, replace the ```` placeholder with the client ID or application ID of the Azure managed identity or enterprise application. .. code-block:: js + :emphasize-lines: 3-4 - const client = new MongoClient("mongodb+srv://@:/?" - + "authMechanism=MONGODB-OIDC" - + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=azure"); + const { MongoClient } = require("mongodb"); + + const uri = "mongodb+srv://@:/?authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=azure"; + const client = new MongoClient(uri); .. _node-mongodb-oidc-gcp-imds: @@ -194,15 +198,19 @@ If your application runs on a Google Compute Engine VM, or otherwise uses the you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP support. -The following code example shows how to specify GCP IMDS OIDC authentication. +The following code example shows how to specify GCP IMDS OIDC as the authentication +mechanism. Replace the ```` placeholder with the value of the ``audience`` parameter configured on your MongoDB deployment. .. code-block:: js + :emphasize-lines: 3-4 - const client = new MongoClient("mongodb+srv://:/?" - + "authMechanism=MONGODB-OIDC" - + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=gcp"); + const { MongoClient } = require("mongodb"); + + const uri = "mongodb+srv://:/?authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=gcp" + const client = new MongoClient(uri); Custom Callback ~~~~~~~~~~~~~~~ @@ -227,7 +235,7 @@ access inside the function: * - Property - Value * - ``timeoutContext`` - - An ``AbortSignal`` that aborts after 30 seconds + - An ``AbortSignal`` that aborts the authentication workflow after 30 seconds * - ``version`` - The current OIDC API version * - ``idpInfo`` @@ -257,7 +265,7 @@ from a file named ``access-token.dat`` in the local file system: .. code-block:: js - import fs from "node:fs"; + const fs = require("node:fs"); const myCallback = (params: OIDCCallbackParams): Promise => { const token = fs.readFileSync("access-token.dat", "utf8"); @@ -270,13 +278,64 @@ from a file named ``access-token.dat`` in the local file system: } After you define your callback function, pass it to the ``MongoClient`` constructor -as part of the ``authMechanismProperties`` parameter, as shown in the following -example: +as part of the ``authMechanismProperties`` parameter. The {+driver-short+} supports +the following authentication patterns: -.. code-block:: js +- **Machine authentication:** Used by web services and other applications that require + no human interaction. Select the :guilabel:`Machine Callback` tab to see an example of + this syntax. +- **Human authentication:** Used by database tools, command-line utilities, and other + applications that involve direct human interaction. Select the :guilabel:`Human Callback` + tab to see an example of this syntax. - const client = new MongoClient("mongodb+srv://:/?authMechanism=MONGODB-OIDC", { - authMechanismProperties: { - OIDC_CALLBACK: oidcCallback - } - }); \ No newline at end of file +.. tabs:: + + .. tab:: Machine Callback + :tabid: machine-callback + + If your application is one that requires no human interaction, such as a web service, + assign the callback function to the + ``authMechanismProperties.OIDC_CALLBACK`` property, as shown in the following + example: + + .. code-block:: js + :emphasize-lines: 4-7 + + const { MongoClient } = require("mongodb"); + + const uri = "mongodb+srv://:/?authMechanism=MONGODB-OIDC"; + const client = new MongoClient(uri, { + authMechanismProperties: { + OIDC_CALLBACK: myCallback + } + }); + + .. tab:: Human Callback + :tabid: human-callback + + If your application is one that involves human interaction, such as a database tool + or command-line utility, assign the callback function to the + ``authMechanismProperties.OIDC_HUMAN_CALLBACK`` property, as shown in the following + example: + + .. code-block:: js + :emphasize-lines: 4-7 + + const { MongoClient } = require("mongodb"); + + const uri = "mongodb+srv://:/?authMechanism=MONGODB-OIDC"; + const client = new MongoClient(uri, { + authMechanismProperties: { + OIDC_CALLBACK: myCallback + } + }); + +API Documentation +----------------- + +To learn more about the methods and types discussed in this +guide, see the following API documentation: + +- `MongoClient <{+api+}/classes/MongoClient.html>`__ +- `OIDCCallbackParams <{+api+}/interfaces/OIDCCallbackParams.html>`__ +- `OIDCResponse <{+api+}/interfaces/OIDCResponse.html>`__ \ No newline at end of file From 842a3d58ea686d5ac2af4e5d73f8a9ad57e6f9af Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:20:16 -0500 Subject: [PATCH 4/6] fixes --- .../authentication/enterprise-mechanisms.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source/fundamentals/authentication/enterprise-mechanisms.txt b/source/fundamentals/authentication/enterprise-mechanisms.txt index b74651cf0..10ee50d9a 100644 --- a/source/fundamentals/authentication/enterprise-mechanisms.txt +++ b/source/fundamentals/authentication/enterprise-mechanisms.txt @@ -209,7 +209,7 @@ value of the ``audience`` parameter configured on your MongoDB deployment. const { MongoClient } = require("mongodb"); const uri = "mongodb+srv://:/?authMechanism=MONGODB-OIDC" - + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=gcp" + + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=gcp"; const client = new MongoClient(uri); Custom Callback @@ -293,8 +293,7 @@ the following authentication patterns: .. tab:: Machine Callback :tabid: machine-callback - If your application is one that requires no human interaction, such as a web service, - assign the callback function to the + For machine authentication, assign the callback function to the ``authMechanismProperties.OIDC_CALLBACK`` property, as shown in the following example: @@ -313,8 +312,7 @@ the following authentication patterns: .. tab:: Human Callback :tabid: human-callback - If your application is one that involves human interaction, such as a database tool - or command-line utility, assign the callback function to the + For human authentication, assign the callback function to the ``authMechanismProperties.OIDC_HUMAN_CALLBACK`` property, as shown in the following example: @@ -327,7 +325,7 @@ the following authentication patterns: const client = new MongoClient(uri, { authMechanismProperties: { OIDC_CALLBACK: myCallback - } + } }); API Documentation From a2f87d4433ea0b82a39931729fb474fe369bff9b Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:24:54 -0500 Subject: [PATCH 5/6] clarify idp --- source/fundamentals/authentication/enterprise-mechanisms.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/fundamentals/authentication/enterprise-mechanisms.txt b/source/fundamentals/authentication/enterprise-mechanisms.txt index 10ee50d9a..c769e14d0 100644 --- a/source/fundamentals/authentication/enterprise-mechanisms.txt +++ b/source/fundamentals/authentication/enterprise-mechanisms.txt @@ -239,7 +239,7 @@ access inside the function: * - ``version`` - The current OIDC API version * - ``idpInfo`` - - The IdP information returned from the server + - The identity-provider information returned from the server * - ``username`` - The username included in the connection string, if any * - ``refreshToken`` From 7661b540ae6c5476836d5e894131c0bca0e74e34 Mon Sep 17 00:00:00 2001 From: Mike Woofter <108414937+mongoKart@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:44:30 -0500 Subject: [PATCH 6/6] feedback --- .../authentication/enterprise-mechanisms.txt | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/source/fundamentals/authentication/enterprise-mechanisms.txt b/source/fundamentals/authentication/enterprise-mechanisms.txt index c769e14d0..ba5aeae84 100644 --- a/source/fundamentals/authentication/enterprise-mechanisms.txt +++ b/source/fundamentals/authentication/enterprise-mechanisms.txt @@ -172,20 +172,28 @@ If your application runs on an Azure VM, or otherwise uses the (IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s built-in Azure support. -The following code example shows how to specify Azure IMDS OIDC as the authentication -mechanism. -Replace the ```` placeholder with the -value of the ``audience`` parameter configured on your MongoDB deployment. -Optionally, replace the ```` placeholder with the client ID or application ID of the -Azure managed identity or enterprise application. - +To specify Azure IMDS OIDC as the authentication mechanism, set the following options +in your connection string: + +- ``username``: If you're using an Azure managed identity, set this to the client ID + of the managed identity. If you're using a service principal to represent an + enterprise application, set this to the application ID of the service principal. + Otherwise, omit this option. +- ``authMechanism``: Set to ``MONGODB-OIDC``. +- ``authMechanismProperties``: Set to + ``ENVIRONMENT:azure,TOKEN_RESOURCE:``. + Replace the ```` placeholder with the + value of the ``audience`` parameter configured on your MongoDB deployment. + +The following code example shows how to set the preceding connection options: + .. code-block:: js :emphasize-lines: 3-4 const { MongoClient } = require("mongodb"); - const uri = "mongodb+srv://@:/?authMechanism=MONGODB-OIDC" - + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=azure"; + const uri = "mongodb+srv://@:/?authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:"; const client = new MongoClient(uri); .. _node-mongodb-oidc-gcp-imds: @@ -198,10 +206,16 @@ If your application runs on a Google Compute Engine VM, or otherwise uses the you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP support. -The following code example shows how to specify GCP IMDS OIDC as the authentication -mechanism. -Replace the ```` placeholder with the -value of the ``audience`` parameter configured on your MongoDB deployment. +To specify GCP IMDS OIDC as the authentication mechanism, set the following options +in your connection string: + +- ``authMechanism``: Set to ``MONGODB-OIDC``. +- ``authMechanismProperties``: Set to + ``ENVIRONMENT:gcp,TOKEN_RESOURCE:``. + Replace the ```` placeholder with the + value of the ``audience`` parameter configured on your MongoDB deployment. + +The following code example shows how to set the preceding connection options: .. code-block:: js :emphasize-lines: 3-4 @@ -209,7 +223,7 @@ value of the ``audience`` parameter configured on your MongoDB deployment. const { MongoClient } = require("mongodb"); const uri = "mongodb+srv://:/?authMechanism=MONGODB-OIDC" - + "&authMechanismProperties=TOKEN_RESOURCE:,ENVIRONMENT=gcp"; + + "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:"; const client = new MongoClient(uri); Custom Callback @@ -324,7 +338,7 @@ the following authentication patterns: const uri = "mongodb+srv://:/?authMechanism=MONGODB-OIDC"; const client = new MongoClient(uri, { authMechanismProperties: { - OIDC_CALLBACK: myCallback + OIDC_HUMAN_CALLBACK: myCallback } });