OIDC: Add Documentation Examples

XMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Done
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Hide

      DRIVERS-2550:
      Summary of necessary driver changes

      •  Add documentation for MONGODB-OIDC to existing authentication documentation.
      • Include examples for:
      • Azure IMDS with connection string
      • Azure Functions/ASE with custom callback
      • Azure AKS token with custom callback
      • GCP IMDS with connection string
      • GCP GKE token with custom callback
      Show
      DRIVERS-2550 : Summary of necessary driver changes  Add documentation for MONGODB-OIDC to existing authentication documentation. Include examples for: Azure IMDS with connection string Azure Functions/ASE with custom callback Azure AKS token with custom callback GCP IMDS with connection string GCP GKE token with custom callback See https://github.com/mongodb/mongo-python-driver/commit/2588ca3782c874fa5b6b80d886f4f5fb6607bdb3 and https://github.com/mongodb/mongo-python-driver/commit/b6f0081cf9d2af20dd9d709a7963edcd802f26b6 from the Python implementation
    • Not Needed
    • 🔵 Done
    • Needed
    • Hide

      Requesting examples be added to https://www.mongodb.com/docs/languages/c/c-driver/current/security/authentication/ to show OIDC authentication.

      Full examples are available on this branch: https://github.com/kevinAlbs/mongo-c-driver/pull/new/doc-examples.C5527 and copied here:

      Azure

      #include <mongoc/mongoc.h>
      
      #define ASSERT_WITH_ERROR(stmt, err)                                                \
         if (!(stmt)) {                                                                   \
            fprintf(stderr, "Error on line %d (%s): %s\n", __LINE__, #stmt, err.message); \
            abort();                                                                      \
         }
      
      #define ASSERT(stmt)                                               \
         if (!(stmt)) {                                                  \
            fprintf(stderr, "Error on line %d (%s)\n", __LINE__, #stmt); \
            abort();                                                     \
         }
      
      int
      main(void)
      {
         bson_error_t error;
      
         // Create client configured with Azure OIDC:
         mongoc_client_t *client;
         {
            mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv("MONGODB_URI"), &error);
            ASSERT_WITH_ERROR(uri, error);
            mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC");
            bson_t mechanism_properties = BSON_INITIALIZER;
            BSON_APPEND_UTF8(&mechanism_properties, "ENVIRONMENT", "azure");
            BSON_APPEND_UTF8(&mechanism_properties, "TOKEN_RESOURCE", "<managed_identity_client_id>");
            ASSERT(mongoc_uri_set_mechanism_properties(uri, &mechanism_properties));
            client = mongoc_client_new_from_uri_with_error(uri, &error);
            ASSERT_WITH_ERROR(client, error);
            bson_destroy(&mechanism_properties);
            mongoc_uri_destroy(uri);
         }
      
         // Insert a document:
         {
            bson_t doc = BSON_INITIALIZER;
            mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "coll");
            ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error);
            mongoc_collection_destroy(coll);
         }
      
         mongoc_client_destroy(client);
         return 0;
      }
      

      GCP

      #include <mongoc/mongoc.h>
      
      #define ASSERT_WITH_ERROR(stmt, err)                                                \
         if (!(stmt)) {                                                                   \
            fprintf(stderr, "Error on line %d (%s): %s\n", __LINE__, #stmt, err.message); \
            abort();                                                                      \
         }
      
      #define ASSERT(stmt)                                               \
         if (!(stmt)) {                                                  \
            fprintf(stderr, "Error on line %d (%s)\n", __LINE__, #stmt); \
            abort();                                                     \
         }
      
      int
      main(void)
      {
         bson_error_t error;
      
         // Create client configured with GCP OIDC:
         mongoc_client_t *client;
         {
            mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv("MONGODB_URI"), &error);
            ASSERT_WITH_ERROR(uri, error);
            mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC");
            bson_t mechanism_properties = BSON_INITIALIZER;
            BSON_APPEND_UTF8(&mechanism_properties, "ENVIRONMENT", "gcp");
            BSON_APPEND_UTF8(&mechanism_properties, "TOKEN_RESOURCE", "<managed_identity_client_id>");
            ASSERT(mongoc_uri_set_mechanism_properties(uri, &mechanism_properties));
            client = mongoc_client_new_from_uri_with_error(uri, &error);
            ASSERT_WITH_ERROR(client, error);
            bson_destroy(&mechanism_properties);
            mongoc_uri_destroy(uri);
         }
      
         // Insert a document:
         {
            bson_t doc = BSON_INITIALIZER;
            mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "coll");
            ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error);
            mongoc_collection_destroy(coll);
         }
      
         mongoc_client_destroy(client);
         return 0;
      }
      

      Custom callback

      #include <mongoc/mongoc.h>
      
      #define ASSERT_WITH_ERROR(stmt, err)                                                \
         if (!(stmt)) {                                                                   \
            fprintf(stderr, "Error on line %d (%s): %s\n", __LINE__, #stmt, err.message); \
            abort();                                                                      \
         }
      
      #define ASSERT(stmt)                                               \
         if (!(stmt)) {                                                  \
            fprintf(stderr, "Error on line %d (%s)\n", __LINE__, #stmt); \
            abort();                                                     \
         }
      
      static mongoc_oidc_credential_t *
      oidc_callback_fn(mongoc_oidc_callback_params_t *params)
      {
         FILE *token_file = fopen("/tmp/tokens/test_machine", "r");
         ASSERT(token_file);
      
         // Determine length of token:
         ASSERT(0 == fseek(token_file, 0, SEEK_END));
         long token_len = ftell(token_file);
         ASSERT(token_len > 0);
         ASSERT(0 == fseek(token_file, 0, SEEK_SET));
      
         // Read file into buffer:
         char *token = bson_malloc(token_len + 1);
         size_t nread = fread(token, 1, token_len, token_file);
         ASSERT(nread == (size_t)token_len);
         token[token_len] = '\0';
         fclose(token_file);
         mongoc_oidc_credential_t *cred = mongoc_oidc_credential_new(token);
         bson_free(token);
         return cred;
      }
      
      int
      main(void)
      {
         bson_error_t error;
      
         // Create client configured with OIDC callback:
         mongoc_client_t *client;
         {
            mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv("MONGODB_URI"), &error);
            ASSERT_WITH_ERROR(uri, error);
            mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC");
            mongoc_oidc_callback_t *oidc_callback = mongoc_oidc_callback_new(oidc_callback_fn);
            client = mongoc_client_new_from_uri_with_error(uri, &error);
            ASSERT_WITH_ERROR(client, error);
            ASSERT(mongoc_client_set_oidc_callback(client, oidc_callback));
            mongoc_oidc_callback_destroy(oidc_callback);
            mongoc_uri_destroy(uri);
         }
      
         // Insert a document:
         {
            bson_t doc = BSON_INITIALIZER;
            mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "coll");
            ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error);
            mongoc_collection_destroy(coll);
         }
      
         mongoc_client_destroy(client);
         return 0;
      }
      

      Quoting DRIVERS-2887 for example descriptions. Examples are on this branch: https://github.com/kevinAlbs/mongo-c-driver/pull/new/doc-examples.C5527

      > Driver name and minimum supported version for OIDC workload

      MongoDB C Driver version 2.2.0. Supports OIDC custom callback, Azure, and GCP. Does not support Kubernetes.

      > Code sample for an OIDC-enabled client with a custom callback

      #include <mongoc/mongoc.h>
      
      #define ASSERT_WITH_ERROR(stmt, err)                                                \
         if (!(stmt)) {                                                                   \
            fprintf(stderr, "Error on line %d (%s): %s\n", __LINE__, #stmt, err.message); \
            abort();                                                                      \
         }
      
      #define ASSERT(stmt)                                               \
         if (!(stmt)) {                                                  \
            fprintf(stderr, "Error on line %d (%s)\n", __LINE__, #stmt); \
            abort();                                                     \
         }
      
      static mongoc_oidc_credential_t *
      oidc_callback_fn(mongoc_oidc_callback_params_t *params)
      {
         FILE *token_file = fopen("/tmp/tokens/test_machine", "r");
         ASSERT(token_file);
      
         // Determine length of token:
         ASSERT(0 == fseek(token_file, 0, SEEK_END));
         long token_len = ftell(token_file);
         ASSERT(token_len > 0);
         ASSERT(0 == fseek(token_file, 0, SEEK_SET));
      
         // Read file into buffer:
         char *token = bson_malloc(token_len + 1);
         size_t nread = fread(token, 1, token_len, token_file);
         ASSERT(nread == (size_t)token_len);
         token[token_len] = '\0';
         fclose(token_file);
         mongoc_oidc_credential_t *cred = mongoc_oidc_credential_new(token);
         bson_free(token);
         return cred;
      }
      
      int
      main(void)
      {
         bson_error_t error;
      
         // Create client configured with OIDC callback:
         mongoc_client_t *client;
         {
            mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv("MONGODB_URI"), &error);
            ASSERT_WITH_ERROR(uri, error);
            mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC");
            mongoc_oidc_callback_t *oidc_callback = mongoc_oidc_callback_new(oidc_callback_fn);
            client = mongoc_client_new_from_uri_with_error(uri, &error);
            ASSERT_WITH_ERROR(client, error);
            ASSERT(mongoc_client_set_oidc_callback(client, oidc_callback));
            mongoc_oidc_callback_destroy(oidc_callback);
            mongoc_uri_destroy(uri);
         }
      
         // Insert a document:
         {
            bson_t doc = BSON_INITIALIZER;
            mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "coll");
            ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error);
            mongoc_collection_destroy(coll);
         }
      
         mongoc_client_destroy(client);
         return 0;
      }
      

      > Code sample for an OIDC-enabled client with an "ENVIRONMENT:azure" callback.

      #include <mongoc/mongoc.h>
      
      #define ASSERT_WITH_ERROR(stmt, err)                                                \
         if (!(stmt)) {                                                                   \
            fprintf(stderr, "Error on line %d (%s): %s\n", __LINE__, #stmt, err.message); \
            abort();                                                                      \
         }
      
      #define ASSERT(stmt)                                               \
         if (!(stmt)) {                                                  \
            fprintf(stderr, "Error on line %d (%s)\n", __LINE__, #stmt); \
            abort();                                                     \
         }
      
      int
      main(void)
      {
         bson_error_t error;
      
         // Create client configured with Azure OIDC:
         mongoc_client_t *client;
         {
            mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv("MONGODB_URI"), &error);
            ASSERT_WITH_ERROR(uri, error);
            mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC");
            bson_t mechanism_properties = BSON_INITIALIZER;
            BSON_APPEND_UTF8(&mechanism_properties, "ENVIRONMENT", "azure");
            BSON_APPEND_UTF8(&mechanism_properties, "TOKEN_RESOURCE", "<managed_identity_client_id>");
            ASSERT(mongoc_uri_set_mechanism_properties(uri, &mechanism_properties));
            client = mongoc_client_new_from_uri_with_error(uri, &error);
            ASSERT_WITH_ERROR(client, error);
            bson_destroy(&mechanism_properties);
            mongoc_uri_destroy(uri);
         }
      
         // Insert a document:
         {
            bson_t doc = BSON_INITIALIZER;
            mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "coll");
            ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error);
            mongoc_collection_destroy(coll);
         }
      
         mongoc_client_destroy(client);
         return 0;
      }
      
      Show
      Requesting examples be added to https://www.mongodb.com/docs/languages/c/c-driver/current/security/authentication/ to show OIDC authentication. Full examples are available on this branch: https://github.com/kevinAlbs/mongo-c-driver/pull/new/doc-examples.C5527 and copied here: Azure #include <mongoc/mongoc.h> #define ASSERT_WITH_ERROR(stmt, err) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s): %s\n" , __LINE__, #stmt, err.message); \ abort(); \ } #define ASSERT(stmt) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s)\n" , __LINE__, #stmt); \ abort(); \ } int main(void) { bson_error_t error; // Create client configured with Azure OIDC: mongoc_client_t *client; { mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv( "MONGODB_URI" ), &error); ASSERT_WITH_ERROR(uri, error); mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC" ); bson_t mechanism_properties = BSON_INITIALIZER; BSON_APPEND_UTF8(&mechanism_properties, "ENVIRONMENT" , "azure" ); BSON_APPEND_UTF8(&mechanism_properties, "TOKEN_RESOURCE" , "<managed_identity_client_id>" ); ASSERT(mongoc_uri_set_mechanism_properties(uri, &mechanism_properties)); client = mongoc_client_new_from_uri_with_error(uri, &error); ASSERT_WITH_ERROR(client, error); bson_destroy(&mechanism_properties); mongoc_uri_destroy(uri); } // Insert a document: { bson_t doc = BSON_INITIALIZER; mongoc_collection_t *coll = mongoc_client_get_collection(client, "db" , "coll" ); ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error); mongoc_collection_destroy(coll); } mongoc_client_destroy(client); return 0; } GCP #include <mongoc/mongoc.h> #define ASSERT_WITH_ERROR(stmt, err) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s): %s\n" , __LINE__, #stmt, err.message); \ abort(); \ } #define ASSERT(stmt) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s)\n" , __LINE__, #stmt); \ abort(); \ } int main(void) { bson_error_t error; // Create client configured with GCP OIDC: mongoc_client_t *client; { mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv( "MONGODB_URI" ), &error); ASSERT_WITH_ERROR(uri, error); mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC" ); bson_t mechanism_properties = BSON_INITIALIZER; BSON_APPEND_UTF8(&mechanism_properties, "ENVIRONMENT" , "gcp" ); BSON_APPEND_UTF8(&mechanism_properties, "TOKEN_RESOURCE" , "<managed_identity_client_id>" ); ASSERT(mongoc_uri_set_mechanism_properties(uri, &mechanism_properties)); client = mongoc_client_new_from_uri_with_error(uri, &error); ASSERT_WITH_ERROR(client, error); bson_destroy(&mechanism_properties); mongoc_uri_destroy(uri); } // Insert a document: { bson_t doc = BSON_INITIALIZER; mongoc_collection_t *coll = mongoc_client_get_collection(client, "db" , "coll" ); ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error); mongoc_collection_destroy(coll); } mongoc_client_destroy(client); return 0; } Custom callback #include <mongoc/mongoc.h> #define ASSERT_WITH_ERROR(stmt, err) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s): %s\n" , __LINE__, #stmt, err.message); \ abort(); \ } #define ASSERT(stmt) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s)\n" , __LINE__, #stmt); \ abort(); \ } static mongoc_oidc_credential_t * oidc_callback_fn(mongoc_oidc_callback_params_t *params) { FILE *token_file = fopen( "/tmp/tokens/test_machine" , "r" ); ASSERT(token_file); // Determine length of token: ASSERT(0 == fseek(token_file, 0, SEEK_END)); long token_len = ftell(token_file); ASSERT(token_len > 0); ASSERT(0 == fseek(token_file, 0, SEEK_SET)); // Read file into buffer: char *token = bson_malloc(token_len + 1); size_t nread = fread(token, 1, token_len, token_file); ASSERT(nread == (size_t)token_len); token[token_len] = '\0' ; fclose(token_file); mongoc_oidc_credential_t *cred = mongoc_oidc_credential_new(token); bson_free(token); return cred; } int main(void) { bson_error_t error; // Create client configured with OIDC callback: mongoc_client_t *client; { mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv( "MONGODB_URI" ), &error); ASSERT_WITH_ERROR(uri, error); mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC" ); mongoc_oidc_callback_t *oidc_callback = mongoc_oidc_callback_new(oidc_callback_fn); client = mongoc_client_new_from_uri_with_error(uri, &error); ASSERT_WITH_ERROR(client, error); ASSERT(mongoc_client_set_oidc_callback(client, oidc_callback)); mongoc_oidc_callback_destroy(oidc_callback); mongoc_uri_destroy(uri); } // Insert a document: { bson_t doc = BSON_INITIALIZER; mongoc_collection_t *coll = mongoc_client_get_collection(client, "db" , "coll" ); ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL, NULL, &error), error); mongoc_collection_destroy(coll); } mongoc_client_destroy(client); return 0; } – Quoting DRIVERS-2887 for example descriptions. Examples are on this branch: https://github.com/kevinAlbs/mongo-c-driver/pull/new/doc-examples.C5527 > Driver name and minimum supported version for OIDC workload MongoDB C Driver version 2.2.0. Supports OIDC custom callback, Azure, and GCP. Does not support Kubernetes. > Code sample for an OIDC-enabled client with a custom callback #include <mongoc/mongoc.h> #define ASSERT_WITH_ERROR(stmt, err) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s): %s\n" , __LINE__, #stmt, err.message); \ abort(); \ } #define ASSERT(stmt) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s)\n" , __LINE__, #stmt); \ abort(); \ } static mongoc_oidc_credential_t * oidc_callback_fn(mongoc_oidc_callback_params_t *params) { FILE *token_file = fopen( "/tmp/tokens/test_machine" , "r" ); ASSERT(token_file); // Determine length of token: ASSERT(0 == fseek(token_file, 0, SEEK_END)); long token_len = ftell(token_file); ASSERT(token_len > 0); ASSERT(0 == fseek(token_file, 0, SEEK_SET)); // Read file into buffer: char *token = bson_malloc(token_len + 1); size_t nread = fread(token, 1, token_len, token_file); ASSERT(nread == (size_t)token_len); token[token_len] = '\0' ; fclose(token_file); mongoc_oidc_credential_t *cred = mongoc_oidc_credential_new(token); bson_free(token); return cred; } int main( void ) { bson_error_t error; // Create client configured with OIDC callback: mongoc_client_t *client; { mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv( "MONGODB_URI" ), &error); ASSERT_WITH_ERROR(uri, error); mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC" ); mongoc_oidc_callback_t *oidc_callback = mongoc_oidc_callback_new(oidc_callback_fn); client = mongoc_client_new_from_uri_with_error(uri, &error); ASSERT_WITH_ERROR(client, error); ASSERT(mongoc_client_set_oidc_callback(client, oidc_callback)); mongoc_oidc_callback_destroy(oidc_callback); mongoc_uri_destroy(uri); } // Insert a document: { bson_t doc = BSON_INITIALIZER; mongoc_collection_t *coll = mongoc_client_get_collection(client, "db" , "coll" ); ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL , NULL , &error), error); mongoc_collection_destroy(coll); } mongoc_client_destroy(client); return 0; } > Code sample for an OIDC-enabled client with an "ENVIRONMENT:azure" callback. #include <mongoc/mongoc.h> #define ASSERT_WITH_ERROR(stmt, err) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s): %s\n" , __LINE__, #stmt, err.message); \ abort(); \ } #define ASSERT(stmt) \ if (!(stmt)) { \ fprintf(stderr, "Error on line %d (%s)\n" , __LINE__, #stmt); \ abort(); \ } int main( void ) { bson_error_t error; // Create client configured with Azure OIDC: mongoc_client_t *client; { mongoc_uri_t *uri = mongoc_uri_new_with_error(getenv( "MONGODB_URI" ), &error); ASSERT_WITH_ERROR(uri, error); mongoc_uri_set_auth_mechanism(uri, "MONGODB-OIDC" ); bson_t mechanism_properties = BSON_INITIALIZER; BSON_APPEND_UTF8(&mechanism_properties, "ENVIRONMENT" , "azure" ); BSON_APPEND_UTF8(&mechanism_properties, "TOKEN_RESOURCE" , " <managed_identity_client_id> " ); ASSERT(mongoc_uri_set_mechanism_properties(uri, &mechanism_properties)); client = mongoc_client_new_from_uri_with_error(uri, &error); ASSERT_WITH_ERROR(client, error); bson_destroy(&mechanism_properties); mongoc_uri_destroy(uri); } // Insert a document: { bson_t doc = BSON_INITIALIZER; mongoc_collection_t *coll = mongoc_client_get_collection(client, "db" , "coll" ); ASSERT_WITH_ERROR(mongoc_collection_insert_one(coll, &doc, NULL , NULL , &error), error); mongoc_collection_destroy(coll); } mongoc_client_destroy(client); return 0; }
    • None
    • None
    • None
    • None
    • None
    • None

      This ticket was split from DRIVERS-2550, please see that ticket for a detailed description.

            Assignee:
            Micah Scott (Inactive)
            Reporter:
            TPM Jira Automations Bot
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: