Skip to content

Commit 0215a7c

Browse files
authored
DRIVERS-1541 Retry KMS decrypt requests on transient errors (#1586)
1 parent 7517681 commit 0215a7c

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,8 @@ explicit session parameter as described in the [Drivers Sessions Specification](
23842384

23852385
## Changelog
23862386

2387+
- 2024-10-09: Add retry prose test.
2388+
23872389
- 2024-07-29: Document range as stable.
23882390

23892391
- 2024-07-22: Make `trimFactor` and `sparsity` optional.

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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3290,3 +3290,109 @@ Assert the returned payload size is greater than the size of `payload_defaults`.
32903290
> [!NOTE]
32913291
> Do not compare the payload contents. The payloads include random data. The `trimFactor` and `sparsity` directly affect
32923292
> the payload size.
3293+
3294+
### 24. KMS Retry Tests
3295+
3296+
The following tests that certain AWS, Azure, and GCP KMS operations are retried on transient errors.
3297+
3298+
This test uses a mock server with configurable failpoints to simulate network failures. To start the server:
3299+
3300+
```
3301+
python -u kms_failpoint_server.py --port 9003
3302+
```
3303+
3304+
See the [TLS tests](#10-kms-tls-tests) for running the mock server on Evergreen. See
3305+
[the mock server implementation](https://github.com/mongodb-labs/drivers-evergreen-tools/blob/4ba50d373652b6fb39239745664637e33e2b01e6/.evergreen/csfle/kms_failpoint_server.py)
3306+
and the
3307+
[C driver tests](https://github.com/mongodb/mongo-c-driver/blob/d934cd5de55af65220816e4fd01ce3f9c0ef1cd4/src/libmongoc/tests/test-mongoc-client-side-encryption.c#L6295)
3308+
for how to configure failpoints.
3309+
3310+
#### Setup
3311+
3312+
1. Start a `mongod` process with **server version 4.2.0 or later**.
3313+
2. Start the failpoint KMS server with: `python -u kms_failpoint_server.py --port 9003`.
3314+
3. Create a `MongoClient` for key vault operations.
3315+
4. Create a `ClientEncryption` object (referred to as `client_encryption`) with `keyVaultNamespace` set to
3316+
`keyvault.datakeys`.
3317+
3318+
The failpoint server is configured using HTTP requests. Example request to simulate a network failure:
3319+
3320+
`curl -X POST https://localhost:9003/set_failpoint/network -d '{"count": 1}' --cacert drivers-evergreen-tools/.evergreen/x509gen/ca.pem`
3321+
3322+
To simulate an HTTP failure, replace `network` with `http`.
3323+
3324+
When the following test cases request setting `masterKey`, use the following values based on the KMS provider:
3325+
3326+
For "aws":
3327+
3328+
```javascript
3329+
{
3330+
"region": "foo",
3331+
"key": "bar",
3332+
"endpoint": "127.0.0.1:9003",
3333+
}
3334+
```
3335+
3336+
For "azure":
3337+
3338+
```javascript
3339+
{
3340+
"keyVaultEndpoint": "127.0.0.1:9003",
3341+
"keyName": "foo",
3342+
}
3343+
```
3344+
3345+
For "gcp":
3346+
3347+
```javascript
3348+
{
3349+
"projectId": "foo",
3350+
"location": "bar",
3351+
"keyRing": "baz",
3352+
"keyName": "qux",
3353+
"endpoint": "127.0.0.1:9003"
3354+
}
3355+
```
3356+
3357+
#### Case 1: createDataKey and encrypt with TCP retry
3358+
3359+
1. Configure the mock server to simulate one network failure.
3360+
2. Call `client_encryption.createDataKey()` with "aws" as the provider. Expect this to succeed. Store the returned key
3361+
ID in a variable named `keyId`.
3362+
3. Configure the mock server to simulate another network failure.
3363+
4. Call `clientEncryption.encrypt` with the following `EncryptOpts` to encrypt the int32 value `123` with the newly
3364+
created key:
3365+
```typescript
3366+
class EncryptOpts {
3367+
keyId : <keyID>,
3368+
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
3369+
}
3370+
```
3371+
Expect this to succeed.
3372+
3373+
Repeat this test with the `azure` and `gcp` masterKeys.
3374+
3375+
#### Case 2: createDataKey and encrypt with HTTP retry
3376+
3377+
1. Configure the mock server to simulate one HTTP failure.
3378+
2. Call `client_encryption.createDataKey()` with "aws" as the provider. Expect this to succeed. Store the returned key
3379+
ID in a variable named `keyId`.
3380+
3. Configure the mock server to simulate another HTTP failure.
3381+
4. Call `clientEncryption.encrypt` with the following `EncryptOpts` to encrypt the int32 value `123` with the newly
3382+
created key:
3383+
```typescript
3384+
class EncryptOpts {
3385+
keyId : <keyID>,
3386+
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
3387+
}
3388+
```
3389+
Expect this to succeed.
3390+
3391+
Repeat this test with the `azure` and `gcp` masterKeys.
3392+
3393+
#### Case 3: createDataKey fails after too many retries
3394+
3395+
1. Configure the mock server to simulate four network failures.
3396+
2. Call `client_encryption.createDataKey()` with "aws" as the provider. Expect this to fail.
3397+
3398+
Repeat this test with the `azure` and `gcp` masterKeys.

0 commit comments

Comments
 (0)