See the detailed instructions in drivers-evergreen-tools for how to set up your environment for OIDC testing.
Drivers MUST run the unified spec tests in all supported OIDC environments. Drivers MUST set the placeholder
authMechanism properties (ENVIRONMENT and TOKEN_RESOURCE, if applicable). These will typically be read from
environment variables set by the test runner, e,g. AZUREOIDC_RESOURCE.
Drivers MUST run the machine prose tests when OIDC_TOKEN_DIR is set. Drivers can either set the ENVIRONMENT:test
auth mechanism property, or use a custom callback that also reads the file.
Drivers can also choose to run the machine prose tests on GCP or Azure VMs, or on the Kubernetes clusters.
Drivers MUST implement all prose tests in this section. Unless otherwise noted, all MongoClient instances MUST be
configured with retryReads=false.
Note
For test cases that create fail points, drivers MUST either use a unique appName or explicitly remove the fail point
callback to prevent interaction between test cases.
After setting up your OIDC
environment,
source the secrets-export.sh file and use the associated env variables in your tests.
1.1 Callback is called during authentication
- Create an OIDC configured client.
- Perform a
findoperation that succeeds. - Assert that the callback was called 1 time.
- Close the client.
1.2 Callback is called once for multiple connections
- Create an OIDC configured client.
- Start 10 threads and run 100
findoperations in each thread that all succeed. - Assert that the callback was called 1 time.
- Close the client.
2.1 Valid Callback Inputs
- Create an OIDC configured client with an OIDC callback that validates its inputs and returns a valid access token.
- Perform a
findoperation that succeeds. - Assert that the OIDC callback was called with the appropriate inputs, including the timeout parameter if possible.
- Close the client.
2.2 OIDC Callback Returns Null
- Create an OIDC configured client with an OIDC callback that returns
null. - Perform a
findoperation that fails. - Close the client.
2.3 OIDC Callback Returns Missing Data
- Create an OIDC configured client with an OIDC callback that returns data not conforming to the
OIDCCredentialwith missing fields. - Perform a
findoperation that fails. - Close the client.
2.4 Invalid Client Configuration with Callback
- Create an OIDC configured client with an OIDC callback and auth mechanism property
ENVIRONMENT:test. - Assert it returns a client configuration error upon client creation, or client connect if your driver validates on connection.
2.5 Invalid use of ALLOWED_HOSTS
-
Create an OIDC configured client with auth mechanism properties
{"ENVIRONMENT": "azure", "ALLOWED_HOSTS": []}. -
Assert it returns a client configuration error upon client creation, or client connect if your driver validates on connection.
-
Create an OIDC configured client with auth mechanism properties
{"OIDC_CALBACK": "<callback object>", "ALLOWED_HOSTS": []}. -
Assert it returns a client configuration error upon client creation, or client connect if your driver validates on connection.
2.6 ALLOWED_HOSTS defaults ignored
If it is possible to validate an authentication without making a connection, for example by instantiating an authenticator class directly, test the following combinations:
-
Create a MongoCredential for OIDC with a machine callback property.
-
Create an Authenticator object for "example.com" that does not result in an error.
-
Create a MongoCredential for OIDC with an
ENVIRONMENTof "test". -
Create an Authenticator object for "example.com" that does not result in an error.
3.1 Authentication failure with cached tokens fetch a new token and retry auth
- Create an OIDC configured client.
- Poison the Client Cache with an invalid access token.
- Perform a
findoperation that succeeds. - Assert that the callback was called 1 time.
- Close the client.
3.2 Authentication failures without cached tokens return an error
- Create an OIDC configured client with an OIDC callback that always returns invalid access tokens.
- Perform a
findoperation that fails. - Assert that the callback was called 1 time.
- Close the client.
3.3 Unexpected error code does not clear the cache
- Create a
MongoClientwith an OIDC callback that returns a valid token. - Set a fail point for
saslStartcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"saslStart"
],
errorCode: 20 // IllegalOperation
}
}- Perform a
findoperation that fails. - Assert that the callback has been called once.
- Perform a
findoperation that succeeds. - Assert that the callback has been called once.
- Close the client.
- Create an OIDC configured client.
- Set a fail point for
findcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find"
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform a
findoperation that succeeds. - Assert that the callback was called 2 times (once during the connection handshake, and again during reauthentication).
- Close the client.
- Create a
MongoClientwhose OIDC callback returns one good token and then bad tokens after the first call. - Perform a
findoperation that succeeds. - Set a fail point for
findcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find"
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform a
findoperation that fails. - Assert that the callback was called 2 times.
- Close the client.
- Create a
MongoClientwhose OIDC callback returns one good token and then bad tokens after the first call. - Perform an
insertoperation that succeeds. - Set a fail point for
insertcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"insert"
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform a
findoperation that fails. - Assert that the callback was called 2 times.
- Close the client.
- Create an OIDC configured client.
- Populate the Client Cache with a valid access token to enforce Speculative Authentication.
- Perform an
insertoperation that succeeds. - Assert that the callback was not called.
- Assert there were no
SaslStartcommands executed. - Set a fail point for
insertcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"insert"
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform an
insertoperation that succeeds. - Assert that the callback was called once.
- Assert there were
SaslStartcommands executed. - Close the client.
Drivers MUST only run the Azure tests when testing on an Azure VM. See instructions in Drivers Evergreen Tools for test setup.
- Create an OIDC configured client with
ENVIRONMENT:azureand a validTOKEN_RESOURCEand no username. - Perform a
findoperation that succeeds. - Close the client.
- Create an OIDC configured client with
ENVIRONMENT:azureand a validTOKEN_RESOURCEand a username of"bad". - Perform a
findoperation that fails. - Close the client.
Drivers that support the Human Authentication Flow MUST implement all prose
tests in this section. Unless otherwise noted, all MongoClient instances MUST be configured with retryReads=false.
The human workflow tests MUST only be run when OIDC_TOKEN_DIR is set.
Note
For test cases that create fail points, drivers MUST either use a unique appName or explicitly remove the fail point
after the test to prevent interaction between test cases.
Drivers MUST be able to authenticate against a server configured with either one or two configured identity providers.
Unless otherwise specified, use MONGODB_URI_SINGLE and the test_user1 token in the OIDC_TOKEN_DIR as the
"access_token", and a dummy "refresh_token" for all tests.
When using an explicit username for the client, we use the token name and the domain name given by OIDC_DOMAIN, e.g.
test_user1@${OIDC_DOMAIN}.
Drivers MUST be able to authenticate using OIDC callback(s) when there is one principal configured.
1.1 Single Principal Implicit Username
- Create an OIDC configured client.
- Perform a
findoperation that succeeds. - Close the client.
1.2 Single Principal Explicit Username
- Create an OIDC configured client with
MONGODB_URI_SINGLEand a username oftest_user1@${OIDC_DOMAIN}. - Perform a
findoperation that succeeds. - Close the client.
1.3 Multiple Principal User 1
- Create an OIDC configured client with
MONGODB_URI_MULTIand username oftest_user1@${OIDC_DOMAIN}. - Perform a
findoperation that succeeds. - Close the client.
1.4 Multiple Principal User 2
- Create an OIDC configured client with
MONGODB_URI_MULTIand username oftest_user2@${OIDC_DOMAIN}. that reads thetest_user2token file. - Perform a
findoperation that succeeds. - Close the client.
1.5 Multiple Principal No User
- Create an OIDC configured client with
MONGODB_URI_MULTIand no username. - Assert that a
findoperation fails. - Close the client.
1.6 Allowed Hosts Blocked
- Create an OIDC configured client with an
ALLOWED_HOSTSthat is an empty list. - Assert that a
findoperation fails with a client-side error. - Close the client.
- Create a client that uses the URL
mongodb://localhost/?authMechanism=MONGODB-OIDC&ignored=example.com, a human callback, and anALLOWED_HOSTSthat contains["example.com"]. - Assert that a
findoperation fails with a client-side error. - Close the client.
1.7 Allowed Hosts in Connection String Ignored
- Create an OIDC configured client with the connection string:
mongodb+srv://example.com/?authMechanism=MONGODB-OIDC&authMechanismProperties=ALLOWED_HOSTS:%5B%22example.com%22%5Dand a Human Callback. - Assert that the creation of the client raises a configuration error.
1.8 Machine IdP with Human Callback
This test MUST only be run when OIDC_IS_LOCAL is set. This indicates that the server is local and not using Atlas. In
this case, MONGODB_URI_SINGLE will be configured with a human user test_user1, and a machine user test_machine.
This test uses the machine user with a human callback, ensuring that the missing clientId in the
PrincipalStepRequest response is handled by the driver.
- Create an OIDC configured client with
MONGODB_URI_SINGLEand a username oftest_machinethat uses thetest_machinetoken. - Perform a find operation that succeeds.
- Close the client.
2.1 Valid Callback Inputs
- Create an OIDC configured client with a human callback that validates its inputs and returns a valid access token.
- Perform a
findoperation that succeeds. Verify that the human callback was called with the appropriate inputs, including the timeout parameter if possible. - Close the client.
2.2 Human Callback Returns Missing Data
- Create an OIDC configured client with a human callback that returns data not conforming to the
OIDCCredentialwith missing fields. - Perform a
findoperation that fails. - Close the client.
2.3 Refresh Token Is Passed To The Callback
- Create a
MongoClientwith a human callback that checks for the presence of a refresh token. - Perform a find operation that succeeds.
- Set a fail point for
findcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find"
],
errorCode: 391
}
}- Perform a
findoperation that succeeds. - Assert that the callback has been called twice.
- Assert that the refresh token was provided to the callback once.
3.1 Uses speculative authentication if there is a cached token
- Create an OIDC configured client with a human callback that returns a valid token.
- Set a fail point for
findcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find"
],
closeConnection: true
}
}- Perform a
findoperation that fails. - Set a fail point for
saslStartcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"saslStart"
],
errorCode: 18
}
}- Perform a
findoperation that succeeds. - Close the client.
3.2 Does not use speculative authentication if there is no cached token
- Create an OIDC configured client with a human callback that returns a valid token.
- Set a fail point for
saslStartcommands of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"saslStart"
],
errorCode: 18
}
}- Perform a
findoperation that fails. - Close the client.
4.1 Succeeds
- Create an OIDC configured client and add an event listener. The following assumes that the driver does not emit
saslStartorsaslContinueevents. If the driver does emit those events, ignore/filter them for the purposes of this test. - Perform a
findoperation that succeeds. - Assert that the human callback has been called once.
- Clear the listener state if possible.
- Force a reauthenication using a fail point of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find"
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform another find operation that succeeds.
- Assert that the human callback has been called twice.
- Assert that the ordering of list started events is [
find], ,find. Note that if the listener stat could not be cleared then there will and be extrafindcommand. - Assert that the list of command succeeded events is [
find]. - Assert that a
findoperation failed once during the command execution. - Close the client.
4.2 Succeeds no refresh
- Create an OIDC configured client with a human callback that does not return a refresh token.
- Perform a
findoperation that succeeds. - Assert that the human callback has been called once.
- Force a reauthenication using a fail point of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find"
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform a
findoperation that succeeds. - Assert that the human callback has been called twice.
- Close the client.
4.3 Succeeds after refresh fails
- Create an OIDC configured client with a callback that returns the
test_user1access token and a bad refresh token. - Perform a
findoperation that succeeds. - Assert that the human callback has been called once.
- Force a reauthenication using a fail point of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find",
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform a
findoperation that succeeds. - Assert that the human callback has been called 2 times.
- Close the client.
4.4 Fails
- Create an OIDC configured client that returns invalid refresh tokens and returns invalid access tokens after the first access.
- Perform a find operation that succeeds (to force a speculative auth).
- Assert that the human callback has been called once.
- Force a reauthenication using a failCommand of the form:
{
configureFailPoint: "failCommand",
mode: {
times: 1
},
data: {
failCommands: [
"find",
],
errorCode: 391 // ReauthenticationRequired
}
}- Perform a find operation that fails.
- Assert that the human callback has been called three times.
- Close the client.