diff --git a/source/auth/auth.md b/source/auth/auth.md index 9f7ba3bbd4..89c89067f3 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1214,14 +1214,15 @@ in the MONGODB-OIDC specification, including sections or blocks that specificall - ENVIRONMENT\ Drivers MUST allow the user to specify the name of a built-in OIDC application environment integration - to use to obtain credentials. If provided, the value MUST be one of `["test", "azure"]`. If both `ENVIRONMENT` and - an [OIDC Callback](#oidc-callback) or [OIDC Human Callback](#oidc-human-callback) are provided for the same - `MongoClient`, the driver MUST raise an error. + to use to obtain credentials. If provided, the value MUST be one of `["test", "azure", "gcp"]`. If both + `ENVIRONMENT` and an [OIDC Callback](#oidc-callback) or [OIDC Human Callback](#oidc-human-callback) are provided for + the same `MongoClient`, the driver MUST raise an error. - TOKEN_RESOURCE\ The URI of the target resource. This property is currently only used and required by the Azure - built-in OIDC provider integration. If `TOKEN_RESOURCE` is provided and `ENVIRONMENT` is not `azure` or - `TOKEN_RESOURCE` is not provided and `ENVIRONMENT` is `azure`, the driver MUST raise an error. + built-in OIDC provider integration. If `TOKEN_RESOURCE` is provided and `ENVIRONMENT` is not one of + `["azure", "gcp"]` or `TOKEN_RESOURCE` is not provided and `ENVIRONMENT` is one of `["azure", "gcp"]`, the driver + MUST raise an error. - OIDC_CALLBACK\ An [OIDC Callback](#oidc-callback) that returns OIDC credentials. Drivers MAY allow the user to @@ -1326,6 +1327,67 @@ For more details, see The callback itself MUST not perform any caching, and the driver MUST cache its tokens in the same way as if a custom callback had been provided by the user. +For details on test environment setup, see the README in +[Drivers-Evergreen-Tools](https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/auth_oidc/azure/README.md). + +**GCP** + +The GCP provider integration is enabled by setting auth mechanism property `ENVIRONMENT:gcp`. + +If enabled, drivers MUST use an internal machine callback that calls the +[Google Cloud VM metadata](https://cloud.google.com/compute/docs/metadata/overview) endpoint and parse the JSON response +body, as follows: + +Make an HTTP GET request to + +``` +http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience= +``` + +with headers + +``` +Accept: application/json +Metadata-Flavor: Google +``` + +where `` is the value of the `TOKEN_RESOURCE` mechanism property. The timeout should equal the +`callbackTimeoutMS` parameter given to the callback. + +Example code for the above using curl, where `$TOKEN_RESOURCE` is the value of the `TOKEN_RESOURCE` mechanism property. + +```bash +curl -X GET \ + -H "Accept: application/json" \ + -H "Metadata-Flavor: Google" \ + --max-time $CALLBACK_TIMEOUT_MS \ + "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=$TOKEN_RESOURCE" +``` + +The JSON response will be in this format: + +```json +{ + "aud": "https://example.com", + "azp": "118153013249117554930", + "exp": 1707488566, + "iat": 1707484966, + "iss": "https://accounts.google.com", + "sub": "118153013249117554930" +} +``` + +The driver MUST use the returned `"access_token"` value as the access token in a `JwtStepRequest`. If the response does +not return a status code of 200, the driver MUST raise an error including the HTTP response body. + +For more details, see [View and query VM metadata](https://cloud.google.com/compute/docs/metadata/querying-metadata). + +The callback itself MUST not perform any caching, and the driver MUST cache its tokens in the same way as if a custom +callback had been provided by the user. + +For details on test environment setup, see the README in +[Drivers-Evergreen-Tools](https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/auth_oidc/gcp/README.md). + #### OIDC Callback Drivers MUST allow users to provide a callback that returns an OIDC access token. The purpose of the callback is to @@ -1992,6 +2054,8 @@ to EC2 instance metadata in ECS, for security reasons, Amazon states it's best p ## Changelog +- 2024-04-03: Added GCP built-in OIDC provider integration. + - 2024-03-29: Updated OIDC test setup and descriptions. - 2024-03-21: Added Azure built-in OIDC provider integration. diff --git a/source/auth/tests/legacy/connection-string.json b/source/auth/tests/legacy/connection-string.json index a5f3c7e085..3c7a6b1d14 100644 --- a/source/auth/tests/legacy/connection-string.json +++ b/source/auth/tests/legacy/connection-string.json @@ -538,6 +538,75 @@ "uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=UnsupportedProperty:unexisted", "valid": false, "credential": null + }, + { + "description": "should recognise the mechanism with azure provider (MONGODB-OIDC)", + "uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo", + "valid": true, + "credential": { + "username": null, + "password": null, + "source": "$external", + "mechanism": "MONGODB-OIDC", + "mechanism_properties": { + "ENVIRONMENT": "azure", + "TOKEN_RESOURCE": "foo" + } + } + }, + { + "description": "should accept a username with azure provider (MONGODB-OIDC)", + "uri": "mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo", + "valid": true, + "credential": { + "username": "user", + "password": null, + "source": "$external", + "mechanism": "MONGODB-OIDC", + "mechanism_properties": { + "ENVIRONMENT": "azure", + "TOKEN_RESOURCE": "foo" + } + } + }, + { + "description": "should accept a username and throw an error for a password with azure provider (MONGODB-OIDC)", + "uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo", + "valid": false, + "credential": null + }, + { + "description": "should throw an exception if no token audience is given for azure provider (MONGODB-OIDC)", + "uri": "mongodb://username@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure", + "valid": false, + "credential": null + }, + { + "description": "should recognise the mechanism with gcp provider (MONGODB-OIDC)", + "uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:foo", + "valid": true, + "credential": { + "username": null, + "password": null, + "source": "$external", + "mechanism": "MONGODB-OIDC", + "mechanism_properties": { + "ENVIRONMENT": "gcp", + "TOKEN_RESOURCE": "foo" + } + } + }, + { + "description": "should throw an error for a username and password with gcp provider (MONGODB-OIDC)", + "uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:foo", + "valid": false, + "credential": null + }, + { + "description": "should throw an error if not TOKEN_RESOURCE with gcp provider (MONGODB-OIDC)", + "uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp", + "valid": false, + "credential": null } ] } diff --git a/source/auth/tests/legacy/connection-string.yml b/source/auth/tests/legacy/connection-string.yml index 081b14ba1c..b35e5c520d 100644 --- a/source/auth/tests/legacy/connection-string.yml +++ b/source/auth/tests/legacy/connection-string.yml @@ -389,4 +389,55 @@ tests: - description: should throw an exception when unsupported auth property is specified (MONGODB-OIDC) uri: mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=UnsupportedProperty:unexisted valid: false - credential: \ No newline at end of file + credential: + credential: +- description: should recognise the mechanism with azure provider (MONGODB-OIDC) + uri: mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo + valid: true + credential: + username: null + password: null + source: $external + mechanism: MONGODB-OIDC + mechanism_properties: + ENVIRONMENT: azure + TOKEN_RESOURCE: foo +- description: should accept a username with azure provider (MONGODB-OIDC) + uri: mongodb://user@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo + valid: true + credential: + username: user + password: null + source: $external + mechanism: MONGODB-OIDC + mechanism_properties: + ENVIRONMENT: azure + TOKEN_RESOURCE: foo +- description: should accept a username and throw an error for a password with azure provider (MONGODB-OIDC) + uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:foo + valid: false + credential: null +- description: should throw an exception if no token audience is given for azure provider (MONGODB-OIDC) + uri: mongodb://username@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:azure + valid: false + credential: null +- description: should recognise the mechanism with gcp provider (MONGODB-OIDC) + uri: mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:foo + valid: true + credential: + username: null + password: null + source: $external + mechanism: MONGODB-OIDC + mechanism_properties: + ENVIRONMENT: gcp + TOKEN_RESOURCE: foo +- description: should throw an error for a username and password with gcp provider + (MONGODB-OIDC) + uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:foo + valid: false + credential: null +- description: should throw an error if not TOKEN_RESOURCE with gcp provider (MONGODB-OIDC) + uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp + valid: false + credential: null diff --git a/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.json b/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.json index 21e247df66..dad0c0a36a 100644 --- a/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.json +++ b/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.json @@ -1,6 +1,6 @@ { "description": "unacknowledged-write", - "schemaVersion": "1.13", + "schemaVersion": "1.16", "createEntities": [ { "client": { @@ -53,11 +53,27 @@ "_id": 2 } } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": {} + }, + "expectResult": [ + { + "_id": 1 + }, + { + "_id": 2 + } + ] } ], "expectLogMessages": [ { "client": "client", + "ignoreExtraMessages": true, "messages": [ { "level": "debug", diff --git a/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.yml b/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.yml index 7d4847e0d9..16ee0e3cc6 100644 --- a/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.yml +++ b/source/command-logging-and-monitoring/tests/logging/unacknowledged-write.yml @@ -1,6 +1,6 @@ description: "unacknowledged-write" -schemaVersion: "1.13" +schemaVersion: "1.16" createEntities: - client: @@ -31,8 +31,18 @@ tests: object: *collection arguments: document: { _id: 2 } + # Force completion of the w: 0 write by executing a find on the same connection + - name: find + object: *collection + arguments: + filter: { } + expectResult: [ + { _id: 1 }, + { _id: 2 } + ] expectLogMessages: - client: *client + ignoreExtraMessages: true messages: - level: debug component: command diff --git a/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.json b/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.json index 4c16d6df11..782cb84a5b 100644 --- a/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.json +++ b/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.json @@ -1,6 +1,6 @@ { "description": "unacknowledgedBulkWrite", - "schemaVersion": "1.0", + "schemaVersion": "1.7", "createEntities": [ { "client": { @@ -64,11 +64,29 @@ ], "ordered": false } + }, + { + "name": "find", + "object": "collection", + "arguments": { + "filter": {} + }, + "expectResult": [ + { + "_id": 1, + "x": 11 + }, + { + "_id": "unorderedBulkWriteInsertW0", + "x": 44 + } + ] } ], "expectEvents": [ { "client": "client", + "ignoreExtraEvents": true, "events": [ { "commandStartedEvent": { diff --git a/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.yml b/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.yml index d7c8ce0d0c..e512b2eb56 100644 --- a/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.yml +++ b/source/command-logging-and-monitoring/tests/monitoring/unacknowledgedBulkWrite.yml @@ -1,6 +1,6 @@ description: "unacknowledgedBulkWrite" -schemaVersion: "1.0" +schemaVersion: "1.7" createEntities: - client: @@ -36,8 +36,18 @@ tests: - insertOne: document: { _id: "unorderedBulkWriteInsertW0", x: 44 } ordered: false + # Force completion of the w: 0 write by executing a find on the same connection + - name: find + object: *collection + arguments: + filter: { } + expectResult: [ + { _id: 1, x: 11 }, + { _id: "unorderedBulkWriteInsertW0", x: 44 } + ] expectEvents: - client: *client + ignoreExtraEvents: true events: - commandStartedEvent: command: