Skip to content

Commit 2588ca3

Browse files
blink1073NoahStapp
andauthored
PYTHON-3601 OIDC: Add Documentation Examples (#1601)
Co-authored-by: Noah Stapp <[email protected]>
1 parent 90906c3 commit 2588ca3

File tree

4 files changed

+169
-1
lines changed

4 files changed

+169
-1
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,4 @@ repos:
9393
# - test/test_bson.py:267: isnt ==> isn't
9494
# - test/versioned-api/crud-api-version-1-strict.json:514: nin ==> inn, min, bin, nine
9595
# - test/test_client.py:188: te ==> the, be, we, to
96-
args: ["-L", "fle,fo,infinit,isnt,nin,te"]
96+
args: ["-L", "fle,fo,infinit,isnt,nin,te,aks"]

doc/api/pymongo/auth_oidc.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:mod:`auth_oidc` -- MONGODB-OIDC Authentication
2+
===========================================================================
3+
4+
.. automodule:: pymongo.auth_oidc
5+
:members:

doc/api/pymongo/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Sub-modules:
2929
.. toctree::
3030
:maxdepth: 2
3131

32+
auth_oidc
3233
change_stream
3334
client_options
3435
client_session

doc/examples/authentication.rst

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,165 @@ would be::
384384
.. _Assume Role: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
385385
.. _EC2 instance: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html
386386
.. _environment variables: https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime
387+
388+
MONGODB-OIDC
389+
------------
390+
.. versionadded:: 4.7
391+
392+
The `MONGODB-OIDC authentication mechanism`_ is available in MongoDB 7.0+ on Linux platforms.
393+
394+
The MONGODB-OIDC mechanism authenticates using an OpenID Connect (OIDC) access token.
395+
The driver supports OIDC for workload identity, defined as an identity you assign to a software workload
396+
(such as an application, service, script, or container) to authenticate and access other services and resources.
397+
398+
Credentials can be configured through the MongoDB URI or as arguments to
399+
:class:`~pymongo.mongo_client.MongoClient`.
400+
401+
Built-in Support
402+
~~~~~~~~~~~~~~~~
403+
404+
The driver has built-in support for Azure IMDS and GCP IMDS environments. Other environments
405+
are supported with `Custom Callbacks`_.
406+
407+
Azure IMDS
408+
^^^^^^^^^^
409+
410+
For an application running on an Azure VM or otherwise using the `Azure Internal Metadata Service`_,
411+
you can use the built-in support for Azure, where "<client_id>" below is the client id of the Azure
412+
managed identity, and ``<audience>`` is the url-encoded ``audience`` `configured on your MongoDB deployment`_.
413+
414+
.. code-block:: python
415+
416+
import os
417+
418+
uri = os.environ["MONGODB_URI"]
419+
420+
props = {"ENVIRONMENT": "azure", "TOKEN_RESOURCE": "<audience>"}
421+
c = MongoClient(
422+
uri,
423+
username="<client_id>",
424+
authMechanism="MONGODB-OIDC",
425+
authMechanismProperties=props,
426+
)
427+
c.test.test.insert_one({})
428+
c.close()
429+
430+
If the application is running on an Azure VM and only one managed identity is associated with the
431+
VM, ``username`` can be omitted.
432+
433+
GCP IMDS
434+
^^^^^^^^
435+
436+
For an application running on an GCP VM or otherwise using the `GCP Internal Metadata Service`_,
437+
you can use the built-in support for GCP, where ``<audience>`` below is the url-encoded ``audience``
438+
`configured on your MongoDB deployment`_.
439+
440+
.. code-block:: python
441+
442+
import os
443+
444+
uri = os.environ["MONGODB_URI"]
445+
446+
props = {"ENVIRONMENT": "gcp", "TOKEN_RESOURCE": "<audience>"}
447+
c = MongoClient(uri, authMechanism="MONGODB-OIDC", authMechanismProperties=props)
448+
c.test.test.insert_one({})
449+
c.close()
450+
451+
452+
Custom Callbacks
453+
~~~~~~~~~~~~~~~~
454+
455+
For environments that are not directly supported by the driver, you can use :class:`~pymongo.auth_oidc.OIDCCallback`.
456+
Some examples are given below.
457+
458+
AWS EKS
459+
^^^^^^^
460+
461+
For an EKS Cluster with a configured `IAM OIDC provider`_, the token can be read from a path given by
462+
the ``AWS_WEB_IDENTITY_TOKEN_FILE`` environment variable.
463+
464+
.. code-block:: python
465+
466+
import os
467+
from pymongo.auth_oidc import OIDCCallback, OIDCCallbackContext, OIDCCallbackResult
468+
469+
470+
class MyCallback(OIDCCallback):
471+
def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult:
472+
with open(os.environ["AWS_WEB_IDENTITY_TOKEN_FILE"]) as fid:
473+
token = fid.read()
474+
return OIDCCallbackResult(access_token=token)
475+
476+
477+
uri = os.environ["MONGODB_URI"]
478+
props = {"OIDC_CALLBACK": MyCallback()}
479+
c = MongoClient(uri, authMechanism="MONGODB-OIDC", authMechanismProperties=props)
480+
c.test.test.insert_one({})
481+
c.close()
482+
483+
484+
Other Azure Environments
485+
^^^^^^^^^^^^^^^^^^^^^^^^
486+
487+
For applications running on Azure Functions, App Service Environment (ASE), or
488+
Azure Kubernetes Service (AKS), you can use the `azure-identity package`_
489+
to fetch the credentials. This example assumes you have set environment variables for
490+
the ``audience`` `configured on your MongoDB deployment`_, and for the client id of the Azure
491+
managed identity.
492+
493+
.. code-block:: python
494+
495+
import os
496+
from azure.identity import DefaultAzureCredential
497+
from pymongo import MongoClient
498+
from pymongo.auth_oidc import OIDCCallback, OIDCCallbackContext, OIDCCallbackResult
499+
500+
audience = os.environ["AZURE_AUDIENCE"]
501+
client_id = os.environ["AZURE_IDENTITY_CLIENT_ID"]
502+
uri = os.environ["MONGODB_URI"]
503+
504+
505+
class MyCallback(OIDCCallback):
506+
def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult:
507+
credential = DefaultAzureCredential(managed_identity_client_id=client_id)
508+
token = credential.get_token(f"{audience}/.default").token
509+
return OIDCCallbackResult(access_token=token)
510+
511+
512+
props = {"OIDC_CALLBACK": MyCallback()}
513+
c = MongoClient(uri, authMechanismProperties=props)
514+
c.test.test.insert_one({})
515+
c.close()
516+
517+
GCP GKE
518+
^^^^^^^
519+
520+
For a Google Kubernetes Engine cluster with a `configured service account`_, the token can be read from the standard
521+
service account token file location.
522+
523+
.. code-block:: python
524+
525+
import os
526+
from pymongo.auth_oidc import OIDCCallback, OIDCCallbackContext, OIDCCallbackResult
527+
528+
529+
class MyCallback(OIDCCallback):
530+
def fetch(self, context: OIDCCallbackContext) -> OIDCCallbackResult:
531+
with open("/var/run/secrets/kubernetes.io/serviceaccount/token") as fid:
532+
token = fid.read()
533+
return OIDCCallbackResult(access_token=token)
534+
535+
536+
uri = os.environ["MONGODB_URI"]
537+
props = {"OIDC_CALLBACK": MyCallback()}
538+
c = MongoClient(uri, authMechanism="MONGODB-OIDC", authMechanismProperties=props)
539+
c.test.test.insert_one({})
540+
c.close()
541+
542+
.. _MONGODB-OIDC authentication mechanism: https://www.mongodb.com/docs/manual/core/security-oidc/
543+
.. _Azure Internal Metadata Service: https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service
544+
.. _configured on your MongoDB deployment: https://www.mongodb.com/docs/manual/reference/parameters/#mongodb-parameter-param.oidcIdentityProviders
545+
.. _GCP Internal Metadata Service: https://cloud.google.com/compute/docs/metadata/querying-metadata
546+
.. _IAM OIDC provider: https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
547+
.. _azure-identity package: https://pypi.org/project/azure-identity/
548+
.. _configured service account: https://cloud.google.com/kubernetes-engine/docs/how-to/service-accounts

0 commit comments

Comments
 (0)