node-mongodb-native
node-mongodb-native copied to clipboard
feat(NODE-5464): OIDC machine and callback workflow
Description
Implements OIDC new machine and human callback workflows.
What is changing?
- Implements the OIDC callback workflow. Specified with
OIDC_CALLBACK
auth mech property. - Implements the OIDC human callback workflow. Specified with
OIDC_HUMAN_CALLBACK
auth mech property. - Implements the OIDC Test machine workflow. Specified with
ENVIRONMENT:test
auth mech property. - Implements the OIDC Azure machine workflow. Specified with
ENVIRONMENT:azure
auth mech property. - Implements the OIDC GCP machine workflow. Specified with
ENVIRONMENT:gcp
auth mech property. - Uses a new generic
TokenCache
for all OIDC authentication that sits at the auth provider level. - Removes the old complex callback workflow global caching.
- Removes the old global Azure token cache.
Is there new documentation needed for these changes?
What is the motivation for this change?
https://github.com/mongodb/specifications/pull/1471 https://github.com/mongodb/specifications/pull/1544 https://github.com/mongodb/specifications/pull/1513
Release Highlight
Support for MONGODB-OIDC Authentication
MONGODB-OIDC
is now supported as an authentication mechanism for MongoDB server versions 7.0+. The currently supported facets to authenticate with are callback authentication, human interaction callback authentication, Azure machine authentication, and GCP machine authentication.
Azure Machine Authentication
The MongoClient
must be instantiated with authMechanism=MONGODB-OIDC
in the URI or in the client options. Additional required auth mechanism properties of TOKEN_RESOURCE
and ENVIRONMENT
are required and another optional username can be provided. Example:
const client = new MongoClient('mongodb+srv://<username>@<host>:<port>/?authMechanism=MONGODB-OIDC&authMechanismProperties=TOKEN_RESOURCE:<azure_token>,ENVIRONMENT=azure');
await client.connect();
GCP Machine Authentication
The MongoClient
must be instantiated with authMechanism=MONGODB-OIDC
in the URI or in the client options. Additional required auth mechanism properties of TOKEN_RESOURCE
and ENVIRONMENT
are required. Example:
const client = new MongoClient('mongodb+srv://<host>:<port>/?authMechanism=MONGODB-OIDC&authMechanismProperties=TOKEN_RESOURCE:<gcp_token>,ENVIRONMENT=gcp');
await client.connect();
Callback Authentication
The user can provide a custom callback to the MongoClient
that returns a valid response with an access token. The callback is provided as an auth mechanism property an has the signature of:
const oidcCallBack = (params: OIDCCallbackParams): Promise<OIDCResponse> => {
// params.timeoutContext is an AbortSignal that will abort after 30 seconds for non-human and 5 minutes for human.
// params.version is the current OIDC API version.
// params.idpInfo is the IdP info returned from the server.
// params.username is the optional username.
// Make a call to get a token.
const token = ...;
return {
accessToken: token,
expiresInSeconds: 300,
refreshToken: token
};
}
const client = new MongoClient('mongodb+srv://<host>:<port>/?authMechanism=MONGODB-OIDC', {
authMechanismProperties: {
OIDC_CALLBACK: oidcCallback
}
});
await client.connect();
For callbacks that require human interaction, set the callback to the OIDC_HUMAN_CALLBACK
property:
const client = new MongoClient('mongodb+srv://<host>:<port>/?authMechanism=MONGODB-OIDC', {
authMechanismProperties: {
OIDC_HUMAAN_CALLBACK: oidcCallback
}
});
await client.connect();
Double check the following
- [x] Ran
npm run check:lint
script - [x] Self-review completed using the steps outlined here
- [x] PR title follows the correct format:
type(NODE-xxxx)[!]: description
- Example:
feat(NODE-1234)!: rewriting everything in coffeescript
- Example:
- [x] Changes are covered by tests
- [ ] New TODOs have a related JIRA ticket
@blink1073 Is there ever a divergence between connection level and client level caching?
I can't find where to respond. Yes, if another connection on the same client has already re-authenticated, we see that the client cache is different (or newer) than the connection cache, and use that instead.
@blink1073 Is there ever a divergence between connection level and client level caching?
I can't find where to respond. Yes, if another connection on the same client has already re-authenticated, we see that the client cache is different (or newer) than the connection cache, and use that instead.
@blink1073 I'm just curious as to what the point of the connection cache is at all? If the client cache is always the source of truth for all connections, isn't it simpler just to always use that and not copy tokens down to all the connections and need to check their values against the client cache?
@blink1073 I'm just curious as to what the point of the connection cache is at all? If the client cache is always the source of truth for all connections, isn't it simpler just to always use that and not copy tokens down to all the connections and need to check their values against the client cache?
It allows us to figure out how to handle a 391 error, whether we actually need to call the callback again. If we get our 391 after another connection, then it would have already updated the client cache, making it different/newer than the connection cache.
https://github.com/mongodb/node-mongodb-native/pull/3912#discussion_r1598862353
I've update to export both TokenCache
and Workflow
as types.