Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4c77c8f
feat(DRIVERS-2903): use custom aws configuration
durran Jan 13, 2025
edd570d
Update source/auth/auth.md
durran Jan 30, 2025
980a808
Update source/auth/auth.md
durran Jan 30, 2025
17e10ff
fix: lint
durran Jan 30, 2025
adb4a41
feat: update fle sepc for custom provider
durran Feb 19, 2025
18da973
chore: note provider on client encryption
durran Feb 19, 2025
54b2843
chore: fix lint
durran Feb 19, 2025
193000c
chore: update options for custom provider
durran Feb 20, 2025
01182c5
fix: lint
durran Feb 20, 2025
576c4fe
fix: lint
durran Feb 20, 2025
39dd4b8
fix: spelling
durran Feb 20, 2025
fc52c4c
fix: spelling
durran Feb 24, 2025
62294fc
chore: throw error in custom aws config
durran Feb 24, 2025
ccb66a5
chore: merge with lookup
durran Mar 3, 2025
454bfc5
fix: lint
durran Mar 3, 2025
f314d9d
test: finish test 2
durran Mar 4, 2025
1abfe65
chore: update tests and spec wording
durran Mar 10, 2025
e548c73
fix: lint
durran Mar 10, 2025
8de7a38
chore: add variable names
durran Mar 11, 2025
52ad07e
chore: provide node example
durran Mar 11, 2025
5ee97b1
test: add notes on called count
durran Mar 12, 2025
b38d118
Update source/auth/auth.md
durran Mar 12, 2025
ca4f02a
Update source/client-side-encryption/client-side-encryption.md
durran Mar 12, 2025
9ca43a2
Update source/client-side-encryption/tests/README.md
durran Mar 12, 2025
d1667db
Update source/client-side-encryption/tests/README.md
durran Mar 12, 2025
ae88390
Update source/client-side-encryption/tests/README.md
durran Mar 12, 2025
fba2869
Update source/auth/auth.md
durran Mar 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions source/auth/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -987,12 +987,29 @@ those credentials will be used by default if AWS auth environment variables are
application. Alternatively, you can create an AWS profile specifically for your MongoDB credentials and set the
`AWS_PROFILE` environment variable to that profile name."

##### Custom Credential Providers

Drivers that choose to use the AWS SDK to fetch credentials MAY also allow users to provide a custom credential provider
as an option to the `MongoClient`. The interface for the option provided depends on the individual language SDK and
drivers MUST consult AWS SDK documentation to determine that format when implementing. The name of the option MUST be
`AWS_CREDENTIAL_PROVIDER` and be part of the authentication mechanism properties options that can be provided to the
client.

Drivers that implement this MAY choose to implement the following scenarios when applicable in their language's SDK:

1. The default SDK credential provider.
2. A custom credential provider chain.
3. A single credential provider of any available SDK options provided by the SDK.

##### Credential Fetching Order

The order in which Drivers MUST search for credentials is:

1. The URI
2. Environment variables
3. Using `AssumeRoleWithWebIdentity` if `AWS_WEB_IDENTITY_TOKEN_FILE` and `AWS_ROLE_ARN` are set.
4. The ECS endpoint if `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` is set. Otherwise, the EC2 endpoint.
3. A custom AWS credential provider if the driver supports it.
4. Using `AssumeRoleWithWebIdentity` if `AWS_WEB_IDENTITY_TOKEN_FILE` and `AWS_ROLE_ARN` are set.
5. The ECS endpoint if `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` is set. Otherwise, the EC2 endpoint.

> [!NOTE]
> See *Should drivers support accessing Amazon EC2 instance metadata in Amazon ECS* in [Q & A](#q-and-a)
Expand Down Expand Up @@ -1306,6 +1323,10 @@ in the MONGODB-OIDC specification, including sections or blocks that specificall
check MUST be performed after SRV record resolution, if applicable. This property is only required for drivers
that support the [Human Authentication Flow](#human-authentication-flow).

- AWS_CREDENTIAL_PROVIDER

A function or object from the AWS SDK that can be used to return AWS credentials.

<span id="built-in-provider-integrations"/>

#### Built-in OIDC Environment Integrations
Expand Down Expand Up @@ -2134,6 +2155,8 @@ practice to avoid this. (See

## Changelog

- 2025-01-29: Add support for custom AWS credential providers.

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

- 2024-08-19: Clarify Reauthentication and Speculative Authentication combination behavior.
Expand Down
8 changes: 8 additions & 0 deletions source/auth/tests/mongodb-aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ SecretAccessKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Token=AQoDYXdzEJr...<remainder of security token>
```

If the driver supports user provided custom AWS credential providers, then the driver MUST also test the above scenarios
2-6 with a user provided `AWS_CREDENTIAL_PROVIDER` auth mechanism property. This value MUST be the default credential
provider from the AWS SDK. If the default provider does not cover all scenarios above, those not covered MAY be skipped.

If the driver supports a custom AWS credential provider, it MUST verify the custom provider was used when testing. This
may be via a custom function or object that wraps the calls to the custom provider and asserts that it was called at
least once.

## Regular credentials

Drivers MUST be able to authenticate by providing a valid access key id and secret access key pair as the username and
Expand Down
46 changes: 41 additions & 5 deletions source/client-side-encryption/client-side-encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ class AutoEncryptionOpts {
// without the MongoDB Enterprise Advanced licensed crypt_shared library.
bypassQueryAnalysis: Optional<Boolean>; // Default false.
keyExpirationMS: Optional<Uint64>; // Default 60000. 0 means "never expire".
credentialProviders: Optional<CredentialProviders>;
}
```

Expand Down Expand Up @@ -475,6 +476,35 @@ See
<span id="GCPKMSOptions"></span> <span id="AWSKMSOptions"></span> <span id="KMSProvider"></span>
<span id="KMSProviders"></span> <span id="AzureAccessToken"></span> <span id="kmsproviders"></span>

#### credentialProviders

The `credentialProviders` property may be specified on [ClientEncryptionOpts](#ClientEncryptionOpts) or
[AutoEncryptionOpts](#AutoEncryptionOpts). Current support is for AWS only, but is designed to be able to accommodate
additional providers in the future. If a custom credential provider is present, it MUST be used instead of the default
flow for fetching automatic credentials and if the `kmsProviders` are not configured for automatic credential fetching
an error MUST be thrown.

```typescript
interface CredentialProviders {
aws?: AWSCredentialProvider
}

// The type of the AWS credential provider is dictated by the AWS SDK's credential provider for the specific
// language.
type AWSCredentialProvider = Function | Object;
```

The following shows an example object of `CredentialProviders` for Node.js:

```typescript
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';

const credentialProviders = {
// Acquire credentials for AWS:
aws: fromNodeProviderChain()
};
```

#### kmsProviders

The `kmsProviders` property may be specified on [ClientEncryptionOpts](#ClientEncryptionOpts) or
Expand Down Expand Up @@ -593,11 +623,14 @@ Once requested, drivers MUST create a new [KMSProviders](#kmsproviders) $P$ acco
[ClientEncryptionOpts](#ClientEncryptionOpts) or [AutoEncryptionOpts](#AutoEncryptionOpts).
2. Initialize $P$ to an empty [KMSProviders](#kmsproviders) object.
3. If $K$ contains an `aws` property, and that property is an empty map:
1. Attempt to obtain credentials $C$ from the environment using similar logic as is detailed in
[the obtaining-AWS-credentials section from the Driver Authentication specification](../auth/auth.md#obtaining-credentials),
but ignoring the case of loading the credentials from a URI
2. If credentials $C$ were successfully loaded, create a new [AWSKMSOptions](#AWSKMSOptions) map from $C$ and insert
that map onto $P$ as the `aws` property.
1. If a custom credential provider is supplied via the `credentialProviders.aws` applicable encryption option, use
that to fetch the credentials from AWS.
2. Otherwise:
1. Attempt to obtain credentials $C$ from the environment using similar logic as is detailed in
[the obtaining-AWS-credentials section from the Driver Authentication specification](../auth/auth.md#obtaining-credentials),
but ignoring the case of loading the credentials from a URI
2. If credentials $C$ were successfully loaded, create a new [AWSKMSOptions](#AWSKMSOptions) map from $C$ and
insert that map onto $P$ as the `aws` property.
4. If $K$ contains an `gcp` property, and that property is an empty map:
1. Attempt to obtain credentials $C$ from the environment logic as is detailed in
[Obtaining GCP Credentials](#obtaining-gcp-credentials).
Expand Down Expand Up @@ -1051,6 +1084,7 @@ interface ClientEncryptionOpts {
keyVaultClient: MongoClient;
keyVaultNamespace: String;
kmsProviders: KMSProviders;
credentialProviders: CredentialProviders;
tlsOptions?: KMSProvidersTLSOptions; // Maps KMS provider to TLS options.
keyExpirationMS: Optional<Uint64>; // Default 60000. 0 means "never expire".
};
Expand Down Expand Up @@ -2420,6 +2454,8 @@ explicit session parameter as described in the [Drivers Sessions Specification](

## Changelog

- 2024-02-19: Add custom options AWS credential provider.

- 2024-10-09: Add retry prose test.

- 2024-07-29: Document range as stable.
Expand Down
57 changes: 57 additions & 0 deletions source/client-side-encryption/tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3683,3 +3683,60 @@ Run an aggregate operation on `db.csfle` with the following pipeline:
```

Expect an exception to be thrown with a message containing the substring `Upgrade`.

### 26. Custom AWS Credentials

These tests require valid AWS credentials for the remote KMS provider via the secrets manager. These tests MUST NOT run
inside an AWS environment that has the same credentials set in order to properly ensure the tests would fail using
on-demand credentials.

#### Case 1: Explicit encryption with credentials and custom credential provider

Create a MongoClient named `setupClient`.

Create a [ClientEncryption](../client-side-encryption.md#clientencryption) object with the following options:

```typescript
class ClientEncryptionOpts {
keyVaultClient: <setupClient>,
keyVaultNamespace: "keyvault.datakeys",
kmsProviders: { "aws": { "accessKeyId": <set from secrets manager>, "secretAccessKey": <set from secrets manager> } },
credentialProviders: { "aws": <default provider from AWS SDK> }
}
```

Assert that an error is thrown.

#### Case 2: Explicit encryption with custom credential provider

Create a MongoClient named `setupClient`.

Create a [ClientEncryption](../client-side-encryption.md#clientencryption) object with the following options:

```typescript
class ClientEncryptionOpts {
keyVaultClient: <setupClient>,
keyVaultNamespace: "keyvault.datakeys",
kmsProviders: { "aws": {} },
credentialProviders: { "aws": <object/function that returns valid credentials from the secrets manager> }
}
```

Use the client encryption to create a datakey using the "aws" KMS provider. This should successfully load and use the
AWS credentials that were provided by the secrets manager for the remote provider. Assert the datakey was created.

#### Case 3: Auto encryption with credentials and custom credential provider

Create a `MongoClient` object with the following options:

```typescript
class AutoEncryptionOpts {
autoEncryption: {
keyVaultNamespace: "keyvault.datakeys",
kmsProviders: { "aws": { "accessKeyId": <set from secrets manager>, "secretAccessKey": <set from secrets manager> } },
credentialProviders: { "aws": <default provider from AWS SDK> }
}
}
```

Assert that an error is thrown.
Loading