Skip to content

Commit 4a46628

Browse files
authored
DRIVERS-3207: Custom AWS credential providers execute earlier (#1838)
1 parent 4244306 commit 4a46628

File tree

3 files changed

+96
-11
lines changed

3 files changed

+96
-11
lines changed

source/auth/auth.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,12 @@ Examples are provided below.
959959
960960
Drivers MUST allow the user to specify an AWS session token for authentication with temporary credentials.
961961
962+
- AWS_CREDENTIAL_PROVIDER
963+
964+
An AWS [Custom Credential Provider](#custom-credential-providers) that returns AWS credentials. Drivers MAY allow
965+
the user to specify an object or function, depending on what is idiomatic for the driver. This property MUST
966+
follow the same API as the driver language's AWS SDK credential provider.
967+
962968
#### Obtaining Credentials
963969

964970
Drivers will need AWS IAM credentials (an access key, a secret access key and optionally a session token) to complete
@@ -1006,8 +1012,8 @@ Drivers MAY expose API for default providers for the following scenarios when ap
10061012
The order in which Drivers MUST search for credentials is:
10071013
10081014
1. The URI
1009-
2. Environment variables
1010-
3. A custom AWS credential provider if the driver supports it.
1015+
2. A custom AWS credential provider if the driver supports it.
1016+
3. Environment variables
10111017
4. Using `AssumeRoleWithWebIdentity` if `AWS_WEB_IDENTITY_TOKEN_FILE` and `AWS_ROLE_ARN` are set.
10121018
5. The ECS endpoint if `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` is set. Otherwise, the EC2 endpoint.
10131019
@@ -2159,6 +2165,8 @@ practice to avoid this. (See
21592165

21602166
## Changelog
21612167

2168+
- 2025-09-10: Update precedence of MONGODB-AWS credential fetching behaviour.
2169+
21622170
- 2025-01-29: Add support for custom AWS credential providers.
21632171

21642172
- 2024-10-02: Add Kubernetes built-in OIDC provider integration.

source/auth/tests/mongodb-aws.md

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Drivers MUST test the following scenarios:
44

5-
1. `Regular Credentials`: Auth via an `ACCESS_KEY_ID` and `SECRET_ACCESS_KEY` pair
5+
1. `Regular Credentials`: Auth via an `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` pair
66
2. `EC2 Credentials`: Auth from an EC2 instance via temporary credentials assigned to the machine
77
3. `ECS Credentials`: Auth from an ECS instance via temporary credentials assigned to the task
88
4. `Assume Role`: Auth via temporary credentials obtained from an STS AssumeRole request
@@ -21,15 +21,41 @@ SecretAccessKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
2121
Token=AQoDYXdzEJr...<remainder of security token>
2222
```
2323

24-
If the driver supports user provided custom AWS credential providers, then the driver MUST also test the above scenarios
25-
2-6 with a user provided `AWS_CREDENTIAL_PROVIDER` auth mechanism property. This value MUST be the default credential
26-
provider from the AWS SDK. If the default provider does not cover all scenarios above, those not covered MAY be skipped.
27-
In these tests the driver MUST also assert that the user provided credential provider was called at least once in each
28-
test.
24+
## Testing custom credential providers
2925

30-
If the driver supports a custom AWS credential provider, it MUST verify the custom provider was used when testing. This
31-
may be via a custom function or object that wraps the calls to the custom provider and asserts that it was called at
32-
least once.
26+
If the driver supports custom AWS credential providers, the driver MUST test the following:
27+
28+
### 1. Custom Credential Provider Authenticates
29+
30+
Scenarios 1-6 from the previous section with a user provided `AWS_CREDENTIAL_PROVIDER` auth mechanism property. This
31+
credentials MAY be obtained from the default credential provider from the AWS SDK. If the default provider does not
32+
cover all scenarios above, those not covered MAY be skipped. In these tests the driver MUST also assert that the user
33+
provided credential provider was called in each test. This may be via a custom function or object that wraps the calls
34+
to the custom provider and asserts that it was called at least once. For test scenarios where the drivers tools scripts
35+
put the credentials in the MONGODB_URI, drivers MAY extract the credentials from the URI and return the AWS credentials
36+
directly from the custom provider instead of using the AWS SDK default provider.
37+
38+
### 2. Custom Credential Provider Authentication Precedence
39+
40+
#### Case 1: Credentials in URI Take Precedence
41+
42+
Create a `MongoClient` configured with AWS auth and credentials in the URI. Example:
43+
`mongodb://<AccessKeyId>:<SecretAccessKey>@localhost:27017/?authMechanism=MONGODB-AWS`
44+
45+
Configure a custom credential provider to pass valid AWS credentials. The provider must track if it was called.
46+
47+
Expect authentication to succeed and the custom credential provider was *not* called.
48+
49+
#### Case 2: Custom Provider Takes Precedence Over Environment Variables
50+
51+
Run this test in an environment with AWS credentials configured as environment variables (e.g. `AWS_ACCESS_KEY_ID`,
52+
`AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`)
53+
54+
Create a `MongoClient` configured to use AWS auth. Example: `mongodb://localhost:27017/?authMechanism=MONGODB-AWS`.
55+
56+
Configure a custom credential provider to pass valid AWS credentials. The provider must track if it was called.
57+
58+
Expect authentication to succeed and the custom credential provider was called.
3359

3460
## Regular credentials
3561

source/client-side-encryption/tests/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3788,6 +3788,57 @@ class AutoEncryptionOpts {
37883788

37893789
Assert that an error is thrown.
37903790

3791+
#### Case 4: ClientEncryption with `credentialProviders` and valid environment variables.
3792+
3793+
Ensure a valid `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are present in the environment.
3794+
3795+
Create a MongoClient named `setupClient`.
3796+
3797+
Create a [ClientEncryption](../client-side-encryption.md#clientencryption) object with the following options:
3798+
3799+
```typescript
3800+
class ClientEncryptionOpts {
3801+
keyVaultClient: <setupClient>,
3802+
keyVaultNamespace: "keyvault.datakeys",
3803+
kmsProviders: { "aws": {} },
3804+
credentialProviders: { "aws": <object/function that returns valid credentials from the secrets manager> }
3805+
}
3806+
```
3807+
3808+
Use the client encryption to create a datakey using the "aws" KMS provider. This should successfully load and use the
3809+
AWS credentials that were provided by the secrets manager for the remote provider. Assert the datakey was created and
3810+
that the custom credential provider was called at least once.
3811+
3812+
An example of this in Node.js:
3813+
3814+
```typescript
3815+
import { ClientEncryption, MongoClient } from 'mongodb';
3816+
3817+
let calledCount = 0;
3818+
const masterKey = {
3819+
region: '<aws region>',
3820+
key: '<key for arn>'
3821+
};
3822+
const keyVaultClient = new MongoClient(process.env.MONGODB_URI);
3823+
const options = {
3824+
keyVaultNamespace: 'keyvault.datakeys',
3825+
kmsProviders: { aws: {} },
3826+
credentialProviders: {
3827+
aws: async () => {
3828+
calledCount++;
3829+
return {
3830+
accessKeyId: process.env.FLE_AWS_KEY,
3831+
secretAccessKey: process.env.FLE_AWS_SECRET
3832+
};
3833+
}
3834+
}
3835+
};
3836+
const clientEncryption = new ClientEncryption(keyVaultClient, options);
3837+
const dk = await clientEncryption.createDataKey('aws', { masterKey });
3838+
expect(dk).to.be.a(Binary);
3839+
expect(calledCount).to.be.greaterThan(0);
3840+
```
3841+
37913842
### 27. Text Explicit Encryption
37923843

37933844
The Text Explicit Encryption tests utilize Queryable Encryption (QE) range protocol V2 and require MongoDB server 8.2.0+

0 commit comments

Comments
 (0)