Skip to content

Commit 8a67edf

Browse files
authored
DOCSP-43473: oidc (#382)
* DOCSP-43473: oidc * vale * fix * wip * log error * dedent * emphasis * fix * MD tech review 1
1 parent a2ffeda commit 8a67edf

File tree

9 files changed

+430
-4
lines changed

9 files changed

+430
-4
lines changed

snooty.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ cmk-long = "Customer Master Key"
2828
dek-long = "Data Encryption Key"
2929
csfle-short = "CSFLE"
3030
csfle-long = "Client-side Field Level Encryption"
31+
mdb-server = "MongoDB Server"

source/connection-troubleshooting.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ instance. For more information about configuring the firewall, see
199199
Check the Number of Connections
200200
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
201201

202-
Each ``MongoClient`` instance supports a maximum number of concurrent open
202+
Each ``Client`` instance supports a maximum number of concurrent open
203203
connections in its connection pool. The configuration parameter ``maxPoolSize``
204204
defines this value and is set to ``100`` by default. If there are already a
205205
number of open connections equal to ``maxPoolSize``, the server waits until

source/fundamentals/enterprise-auth.txt

Lines changed: 286 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,16 +197,301 @@ address of your MongoDB server:
197197
authenticates using the PLAIN Simple Authentication and Security Layer
198198
(SASL) defined in `RFC-4616 <https://tools.ietf.org/html/rfc4616>`__.
199199

200+
.. _golang-mongodb-oidc:
201+
202+
MONGODB-OIDC
203+
------------
204+
205+
.. important::
206+
207+
The MONGODB-OIDC authentication mechanism requires {+mdb-server+}
208+
v7.0 or later running on a Linux platform.
209+
210+
The {+driver-short+} supports OpenID Connect (**OIDC**) authentication for **workload
211+
identities**. A workload identity is an identity you assign to a
212+
software workload, such as an application, service, script, or
213+
container, to authenticate and access other services and resources.
214+
215+
The following sections describe how to use the MONGODB-OIDC
216+
authentication mechanism to authenticate to various platforms.
217+
218+
To learn more about the MONGODB-OIDC authentication mechanism, see
219+
:manual:`OpenID Connect Authentication </core/security-oidc/>` and
220+
:manual:`MongoDB Server Parameters </reference/parameters/#mongodb-parameter-param.oidcIdentityProviders>`
221+
in the {+mdb-server+} manual.
222+
223+
.. _golang-mongodb-oidc-azure-imds:
224+
225+
Azure IMDS
226+
~~~~~~~~~~
227+
228+
If your application runs on an Azure VM, or otherwise uses the
229+
`Azure Instance Metadata Service <https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service>`__
230+
(IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s
231+
built-in Azure support.
232+
233+
You can configure OIDC for Azure IMDS in the following ways:
234+
235+
- By creating a ``Credential`` struct and passing it to the
236+
``SetAuth()`` method when creating a client
237+
- By setting parameters in your connection string
238+
239+
.. include:: /includes/authentication/auth-properties-commas.rst
240+
241+
.. tabs::
242+
243+
.. tab:: Credential
244+
:tabid: credential struct
245+
246+
First, create a map to store your authentication
247+
mechanism properties, as shown in the following example. Replace
248+
the ``<audience>`` placeholder with the value of the ``audience``
249+
parameter configured on your MongoDB deployment.
250+
251+
.. code-block:: go
252+
253+
props := map[string]string{
254+
"ENVIRONMENT": "azure",
255+
"TOKEN_RESOURCE": "<audience>",
256+
}
257+
258+
Then, set the following ``Credential`` struct fields:
259+
260+
- ``Username``: If you're using an Azure managed identity, set this to the client ID
261+
of the managed identity. If you're using a service principal to represent an
262+
enterprise application, set this to the application ID of the service principal.
263+
- ``AuthMechanism``: Set to ``"MONGODB-OIDC"``.
264+
- ``AuthMechanismProperties``: Set to the ``props`` map that you
265+
previously created.
266+
267+
The following code example shows how to set these options when creating a
268+
``Client``:
269+
270+
.. literalinclude:: /includes/authentication/azure-imds-client.go
271+
:dedent:
272+
:language: go
273+
:copyable: true
274+
:start-after: start-azure-imds-client
275+
:end-before: end-azure-imds-client
276+
:emphasize-lines: 9-11
277+
278+
.. tab:: Connection String
279+
:tabid: connectionstring
280+
281+
Include the following connection options in your connection string:
282+
283+
- ``username``: If you're using an Azure managed identity, set this to the client ID
284+
of the managed identity. If you're using a service principal to represent an
285+
enterprise application, set this to the application ID of the service principal.
286+
- ``authMechanism``: Set to ``MONGODB-OIDC``.
287+
- ``authMechanismProperties``: Set to
288+
``ENVIRONMENT:azure,TOKEN_RESOURCE:<audience>``.
289+
Replace the ``<audience>`` placeholder with the
290+
value of the ``audience`` parameter configured on your MongoDB deployment.
291+
292+
The following code example shows how to set these options in
293+
your connection string:
294+
295+
.. code-block:: go
296+
297+
uri := "mongodb://<hostname>:<port>/?" +
298+
"username=<Azure client ID or application ID>" +
299+
"&authMechanism=MONGODB-OIDC" +
300+
"&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>"
301+
302+
client, err := mongo.Connect(options.Client().ApplyURI(uri))
303+
if err != nil {
304+
panic(err)
305+
}
306+
307+
.. tip::
308+
309+
If your application is running on an Azure VM, and only one managed identity is
310+
associated with the VM, you can omit the ``username`` connection option.
311+
312+
.. _golang-mongodb-oidc-gcp-imds:
313+
314+
GCP IMDS
315+
~~~~~~~~
316+
317+
If your application runs on a Google Compute Engine VM, or otherwise uses the
318+
`GCP Instance Metadata Service <https://cloud.google.com/compute/docs/metadata/querying-metadata>`__,
319+
you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP
320+
support.
321+
322+
You can configure OIDC for GCP IMDS in the following ways:
323+
324+
- By creating a ``Credential`` struct and passing it to the
325+
``SetAuth()`` method when creating a client
326+
- By setting parameters in your connection string
327+
328+
.. include:: /includes/authentication/auth-properties-commas.rst
329+
330+
.. tabs::
331+
332+
.. tab:: Credential
333+
:tabid: credential struct
334+
335+
First, create a map to store your authentication
336+
mechanism properties, as shown in the following example. Replace
337+
the ``<audience>`` placeholder with the value of the ``audience``
338+
parameter configured on your MongoDB deployment.
339+
340+
.. code-block:: go
341+
342+
props := map[string]string{
343+
"ENVIRONMENT": "gcp",
344+
"TOKEN_RESOURCE": "<audience>",
345+
}
346+
347+
Then, set the following ``Credential`` struct fields:
348+
349+
- ``AuthMechanism``: Set to ``"MONGODB-OIDC"``.
350+
- ``AuthMechanismProperties``: Set to the ``props`` map that you
351+
previously created.
352+
353+
The following code example shows how to set these options when creating a
354+
``Client``:
355+
356+
.. literalinclude:: /includes/authentication/gcp-imds-client.go
357+
:language: go
358+
:dedent:
359+
:copyable: true
360+
:start-after: start-gcp-imds-client
361+
:end-before: end-gcp-imds-client
362+
:emphasize-lines: 9-10
363+
364+
.. tab:: Connection String
365+
:tabid: connectionstring
366+
367+
Include the following connection options in your connection string:
368+
369+
- ``authMechanism``: Set to ``MONGODB-OIDC``.
370+
- ``authMechanismProperties``: Set to
371+
``ENVIRONMENT:gcp,TOKEN_RESOURCE:<audience>``.
372+
Replace the ``<audience>`` placeholder with the
373+
value of the ``audience`` parameter configured on your MongoDB deployment.
374+
375+
The following code example shows how to set these options in your connection string:
376+
377+
.. code-block:: go
378+
379+
uri := "mongodb://<hostname>:<port>/?" +
380+
"&authMechanism=MONGODB-OIDC" +
381+
"&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>"
382+
383+
client, err := mongo.Connect(options.Client().ApplyURI(uri))
384+
if err != nil {
385+
panic(err)
386+
}
387+
388+
.. _golang-mongodb-oidc-custom-callback:
389+
390+
Custom Callback
391+
~~~~~~~~~~~~~~~
392+
393+
The {+driver-short+} doesn't offer built-in support for all platforms,
394+
including the AWS Elastic Kubernetes Service (EKS). To authenticate
395+
against unsupported platforms, you must define a custom callback
396+
function to use OIDC to authenticate. In the driver, you can define an
397+
``options.OIDCCallback`` function and set it as the value of the
398+
``OIDCMachineCallback`` struct field in your ``Credential`` struct.
399+
400+
The following example defines a custom callback for an EKS
401+
cluster with a configured IAM OIDC provider. The access token is
402+
read from a path set in the ``AWS_WEB_IDENTITY_TOKEN_FILE``
403+
environment variable:
404+
405+
.. literalinclude:: /includes/authentication/eks-custom-callback.go
406+
:language: go
407+
:dedent:
408+
:copyable: true
409+
:start-after: start-custom-callback
410+
:end-before: end-custom-callback
411+
412+
Then, you can create a ``Credential`` struct that uses the EKS callback
413+
function that you defined:
414+
415+
.. literalinclude:: /includes/authentication/eks-custom-callback.go
416+
:language: go
417+
:dedent:
418+
:copyable: true
419+
:start-after: start-credential-callback
420+
:end-before: end-credential-callback
421+
:emphasize-lines: 6
422+
423+
.. _golang-mongodb-oidc-azure-envs:
424+
425+
Other Azure Environments
426+
~~~~~~~~~~~~~~~~~~~~~~~~
427+
428+
If your application runs on Azure Functions, App Service Environment (ASE), or Azure
429+
Kubernetes Service (AKS), you can use the `azidentity
430+
<https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity>`__
431+
module to fetch authentication credentials.
432+
433+
First, install the ``azidentity`` module by running the
434+
following command:
435+
436+
.. code-block:: sh
437+
438+
go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
439+
440+
Your ``OIDCCallback`` function must return an ``OIDCCredential``
441+
instance that uses the ``AccessToken`` generated from the ``azidentity``
442+
package. See the preceding :ref:`golang-mongodb-oidc-custom-callback`
443+
section for an example that implements a custom callback to retrieve an
444+
access token and then creates a ``Credential``.
445+
446+
.. _golang-mongodb-oidc-gcp-gke:
447+
448+
GCP GKE
449+
~~~~~~~
450+
451+
If your application runs on a GCP Google Kubernetes Engine (GKE) cluster with a
452+
`configured service account
453+
<https://cloud.google.com/kubernetes-engine/docs/how-to/service-accounts>`__,
454+
you can read the OIDC token from the standard service-account token-file location.
455+
456+
First, define the ``OIDCCallback`` function. This function reads the
457+
OIDC token and returns an ``OIDCCredential`` instance.
458+
459+
The following example defines a callback function named ``gkeCallback``.
460+
The function retrieves an OIDC token from a file in the standard
461+
service-account token-file location:
462+
463+
.. literalinclude:: /includes/authentication/gke-callback.go
464+
:language: go
465+
:copyable: true
466+
:dedent:
467+
:start-after: start-callback
468+
:end-before: end-callback
469+
470+
Then, you can create a ``Credential`` struct that uses the the GKE
471+
callback function that you defined:
472+
473+
.. literalinclude:: /includes/authentication/gke-callback.go
474+
:language: go
475+
:copyable: true
476+
:dedent:
477+
:start-after: start-credential-callback
478+
:end-before: end-credential-callback
479+
:emphasize-lines: 6
480+
200481
Additional Information
201482
----------------------
202483

203484
To learn more about the concepts in this guide, see the following documentation:
204485

205486
- :manual:`MongoDB Server Support for Kerberos Authentication </core/kerberos/>`
206487
- :manual:`MongoDB Server Support for LDAP Proxy Authentication </core/security-ldap/>`
488+
- :atlas:`Authentication and Authorization with OIDC/OAuth 2.0 </security-oidc/>`
207489

208490
API Documentation
209491
~~~~~~~~~~~~~~~~~
210492

211493
- `Credential <{+api+}/mongo/options#Credential>`__ type
212-
- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ method
494+
- `SetAuth() <{+api+}/mongo/options#ClientOptions.SetAuth>`__ method
495+
496+
.. TODO - `OIDCCredential <{+api+}/...>`__ type
497+
.. TODO - `OIDCCallback <{+api+}/...>`__ function
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.. note::
2+
3+
If your ``AuthMechanismProperties`` struct field values
4+
include a comma, you must create a ``Credential`` instance
5+
to set your authentication options.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import (
4+
"go.mongodb.org/mongo-driver/mongo"
5+
"go.mongodb.org/mongo-driver/mongo/options"
6+
)
7+
8+
func main() {
9+
// start-azure-imds-client
10+
uri := "mongodb://<hostname>:<port>"
11+
props := map[string]string{
12+
"ENVIRONMENT": "azure",
13+
"TOKEN_RESOURCE": "<audience>",
14+
}
15+
opts := options.Client().ApplyURI(uri)
16+
opts.SetAuth(
17+
options.Credential{
18+
Username: "<Azure client ID or application ID>",
19+
AuthMechanism: "MONGODB-OIDC",
20+
AuthMechanismProperties: props,
21+
},
22+
)
23+
client, err := mongo.Connect(opts)
24+
if err != nil {
25+
panic(err)
26+
}
27+
// end-azure-imds-client
28+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"os"
6+
7+
"go.mongodb.org/mongo-driver/mongo"
8+
"go.mongodb.org/mongo-driver/mongo/options"
9+
)
10+
11+
func main() {
12+
// start-custom-callback
13+
eksCallback := func(_ context.Context,
14+
_ *options.OIDCArgs) (*options.OIDCCredential, error) {
15+
accessToken, err := os.ReadFile(
16+
os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE"))
17+
if err != nil {
18+
return nil, err
19+
}
20+
return &options.OIDCCredential{
21+
AccessToken: string(accessToken),
22+
}, nil
23+
}
24+
// end-custom-callback
25+
26+
// start-credential-callback
27+
uri := "mongodb://<hostname>:<port>"
28+
opts := options.Client().ApplyURI(uri)
29+
opts.SetAuth(
30+
options.Credential{
31+
AuthMechanism: "MONGODB-OIDC",
32+
OIDCMachineCallback: eksCallback,
33+
},
34+
)
35+
client, err := mongo.Connect(opts)
36+
if err != nil {
37+
panic(err)
38+
}
39+
// end-credential-callback
40+
}

0 commit comments

Comments
 (0)