Skip to content

Commit 4d209ce

Browse files
feat(NODE-5801): allow multiple providers providers per type (#4137)
1 parent 0655c73 commit 4d209ce

23 files changed

+3495
-152
lines changed

.evergreen/config.in.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ functions:
135135
export CLIENT_ENCRYPTION=${CLIENT_ENCRYPTION}
136136
export RUN_WITH_MONGOCRYPTD=${RUN_WITH_MONGOCRYPTD}
137137
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
138+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
139+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
138140
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
139141
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
140142
export AWS_REGION='${AWS_REGION}'
@@ -193,6 +195,8 @@ functions:
193195
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
194196
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
195197
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
198+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
199+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
196200
export AWS_REGION='${AWS_REGION}'
197201
export AWS_CMK_ID='${AWS_CMK_ID}'
198202
export AWS_DEFAULT_REGION='us-east-1'
@@ -471,6 +475,8 @@ functions:
471475
cat <<EOT > prepare_client_encryption.sh
472476
export CLIENT_ENCRYPTION='${CLIENT_ENCRYPTION}'
473477
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
478+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
479+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
474480
export AWS_REGION='${AWS_REGION}'
475481
export AWS_CMK_ID='${AWS_CMK_ID}'
476482
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
@@ -908,6 +914,8 @@ functions:
908914
cat <<EOT > prepare_client_encryption.sh
909915
export CLIENT_ENCRYPTION='${CLIENT_ENCRYPTION}'
910916
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
917+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
918+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
911919
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
912920
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
913921
export AWS_REGION='${AWS_REGION}'

.evergreen/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ functions:
108108
export CLIENT_ENCRYPTION=${CLIENT_ENCRYPTION}
109109
export RUN_WITH_MONGOCRYPTD=${RUN_WITH_MONGOCRYPTD}
110110
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
111+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
112+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
111113
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
112114
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
113115
export AWS_REGION='${AWS_REGION}'
@@ -165,6 +167,8 @@ functions:
165167
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
166168
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
167169
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
170+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
171+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
168172
export AWS_REGION='${AWS_REGION}'
169173
export AWS_CMK_ID='${AWS_CMK_ID}'
170174
export AWS_DEFAULT_REGION='us-east-1'
@@ -425,6 +429,8 @@ functions:
425429
cat <<EOT > prepare_client_encryption.sh
426430
export CLIENT_ENCRYPTION='${CLIENT_ENCRYPTION}'
427431
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
432+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
433+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
428434
export AWS_REGION='${AWS_REGION}'
429435
export AWS_CMK_ID='${AWS_CMK_ID}'
430436
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
@@ -881,6 +887,8 @@ functions:
881887
cat <<EOT > prepare_client_encryption.sh
882888
export CLIENT_ENCRYPTION='${CLIENT_ENCRYPTION}'
883889
export CSFLE_KMS_PROVIDERS='${CSFLE_KMS_PROVIDERS}'
890+
export FLE_AWS_KEY2='${FLE_AWS_KEY2}'
891+
export FLE_AWS_SECRET2='${FLE_AWS_SECRET2}'
884892
export AWS_ACCESS_KEY_ID='${AWS_ACCESS_KEY_ID}'
885893
export AWS_SECRET_ACCESS_KEY='${AWS_SECRET_ACCESS_KEY}'
886894
export AWS_REGION='${AWS_REGION}'

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,9 @@ node-artifacts
9696
# AWS SAM generated
9797
test/lambda/.aws-sam
9898
test/lambda/env.json
99+
100+
# files generated by tooling in drivers-evergreen-tools
101+
secrets-export.sh
102+
mo-expansion.sh
103+
mo-expansion.yml
104+
expansions.sh

src/client-side-encryption/providers/index.ts

Lines changed: 120 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -4,124 +4,152 @@ import { loadGCPCredentials } from './gcp';
44

55
/**
66
* @public
7+
*
8+
* A data key provider. Allowed values:
9+
*
10+
* - aws, gcp, local, kmip or azure
11+
* - (`mongodb-client-encryption>=6.0.1` only) a named key, in the form of:
12+
* `aws:<name>`, `gcp:<name>`, `local:<name>`, `kmip:<name>`, `azure:<name>`
13+
* where `name` is an alphanumeric string, underscores allowed.
714
*/
8-
export type ClientEncryptionDataKeyProvider = 'aws' | 'azure' | 'gcp' | 'local' | 'kmip';
15+
export type ClientEncryptionDataKeyProvider = string;
16+
17+
/** @public */
18+
export interface AWSKMSProviderConfiguration {
19+
/**
20+
* The access key used for the AWS KMS provider
21+
*/
22+
accessKeyId: string;
23+
24+
/**
25+
* The secret access key used for the AWS KMS provider
26+
*/
27+
secretAccessKey: string;
28+
29+
/**
30+
* An optional AWS session token that will be used as the
31+
* X-Amz-Security-Token header for AWS requests.
32+
*/
33+
sessionToken?: string;
34+
}
35+
36+
/** @public */
37+
export interface LocalKMSProviderConfiguration {
38+
/**
39+
* The master key used to encrypt/decrypt data keys.
40+
* A 96-byte long Buffer or base64 encoded string.
41+
*/
42+
key: Buffer | string;
43+
}
44+
45+
/** @public */
46+
export interface KMIPKMSProviderConfiguration {
47+
/**
48+
* The output endpoint string.
49+
* The endpoint consists of a hostname and port separated by a colon.
50+
* E.g. "example.com:123". A port is always present.
51+
*/
52+
endpoint?: string;
53+
}
54+
55+
/** @public */
56+
export type AzureKMSProviderConfiguration =
57+
| {
58+
/**
59+
* The tenant ID identifies the organization for the account
60+
*/
61+
tenantId: string;
62+
63+
/**
64+
* The client ID to authenticate a registered application
65+
*/
66+
clientId: string;
67+
68+
/**
69+
* The client secret to authenticate a registered application
70+
*/
71+
clientSecret: string;
72+
73+
/**
74+
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
75+
* This is optional, and only needed if customer is using a non-commercial Azure instance
76+
* (e.g. a government or China account, which use different URLs).
77+
* Defaults to "login.microsoftonline.com"
78+
*/
79+
identityPlatformEndpoint?: string | undefined;
80+
}
81+
| {
82+
/**
83+
* If present, an access token to authenticate with Azure.
84+
*/
85+
accessToken: string;
86+
};
87+
88+
/** @public */
89+
export type GCPKMSProviderConfiguration =
90+
| {
91+
/**
92+
* The service account email to authenticate
93+
*/
94+
email: string;
95+
96+
/**
97+
* A PKCS#8 encrypted key. This can either be a base64 string or a binary representation
98+
*/
99+
privateKey: string | Buffer;
100+
101+
/**
102+
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
103+
* Defaults to "oauth2.googleapis.com"
104+
*/
105+
endpoint?: string | undefined;
106+
}
107+
| {
108+
/**
109+
* If present, an access token to authenticate with GCP.
110+
*/
111+
accessToken: string;
112+
};
9113

10114
/**
11115
* @public
12116
* Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.
117+
*
118+
* Named KMS providers _are not supported_ for automatic KMS credential fetching.
13119
*/
14120
export interface KMSProviders {
15121
/**
16122
* Configuration options for using 'aws' as your KMS provider
17123
*/
18-
aws?:
19-
| {
20-
/**
21-
* The access key used for the AWS KMS provider
22-
*/
23-
accessKeyId: string;
24-
25-
/**
26-
* The secret access key used for the AWS KMS provider
27-
*/
28-
secretAccessKey: string;
29-
30-
/**
31-
* An optional AWS session token that will be used as the
32-
* X-Amz-Security-Token header for AWS requests.
33-
*/
34-
sessionToken?: string;
35-
}
36-
| Record<string, never>;
124+
aws?: AWSKMSProviderConfiguration | Record<string, never>;
37125

38126
/**
39127
* Configuration options for using 'local' as your KMS provider
40128
*/
41-
local?: {
42-
/**
43-
* The master key used to encrypt/decrypt data keys.
44-
* A 96-byte long Buffer or base64 encoded string.
45-
*/
46-
key: Buffer | string;
47-
};
129+
local?: LocalKMSProviderConfiguration;
48130

49131
/**
50132
* Configuration options for using 'kmip' as your KMS provider
51133
*/
52-
kmip?: {
53-
/**
54-
* The output endpoint string.
55-
* The endpoint consists of a hostname and port separated by a colon.
56-
* E.g. "example.com:123". A port is always present.
57-
*/
58-
endpoint?: string;
59-
};
134+
kmip?: KMIPKMSProviderConfiguration;
60135

61136
/**
62137
* Configuration options for using 'azure' as your KMS provider
63138
*/
64-
azure?:
65-
| {
66-
/**
67-
* The tenant ID identifies the organization for the account
68-
*/
69-
tenantId: string;
70-
71-
/**
72-
* The client ID to authenticate a registered application
73-
*/
74-
clientId: string;
75-
76-
/**
77-
* The client secret to authenticate a registered application
78-
*/
79-
clientSecret: string;
80-
81-
/**
82-
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
83-
* This is optional, and only needed if customer is using a non-commercial Azure instance
84-
* (e.g. a government or China account, which use different URLs).
85-
* Defaults to "login.microsoftonline.com"
86-
*/
87-
identityPlatformEndpoint?: string | undefined;
88-
}
89-
| {
90-
/**
91-
* If present, an access token to authenticate with Azure.
92-
*/
93-
accessToken: string;
94-
}
95-
| Record<string, never>;
139+
azure?: AzureKMSProviderConfiguration | Record<string, never>;
96140

97141
/**
98142
* Configuration options for using 'gcp' as your KMS provider
99143
*/
100-
gcp?:
101-
| {
102-
/**
103-
* The service account email to authenticate
104-
*/
105-
email: string;
106-
107-
/**
108-
* A PKCS#8 encrypted key. This can either be a base64 string or a binary representation
109-
*/
110-
privateKey: string | Buffer;
111-
112-
/**
113-
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
114-
* Defaults to "oauth2.googleapis.com"
115-
*/
116-
endpoint?: string | undefined;
117-
}
118-
| {
119-
/**
120-
* If present, an access token to authenticate with GCP.
121-
*/
122-
accessToken: string;
123-
}
124-
| Record<string, never>;
144+
gcp?: GCPKMSProviderConfiguration | Record<string, never>;
145+
146+
[key: string]:
147+
| AWSKMSProviderConfiguration
148+
| LocalKMSProviderConfiguration
149+
| KMIPKMSProviderConfiguration
150+
| AzureKMSProviderConfiguration
151+
| GCPKMSProviderConfiguration
152+
| undefined;
125153
}
126154

127155
/**

src/client-side-encryption/state_machine.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { BufferPool, MongoDBCollectionNamespace, promiseWithResolvers } from '..
1717
import { type DataKey } from './client_encryption';
1818
import { MongoCryptError } from './errors';
1919
import { type MongocryptdManager } from './mongocryptd_manager';
20-
import { type ClientEncryptionDataKeyProvider, type KMSProviders } from './providers';
20+
import { type KMSProviders } from './providers';
2121

2222
let socks: SocksLib | null = null;
2323
function loadSocks(): SocksLib {
@@ -110,6 +110,8 @@ export type CSFLEKMSTlsOptions = {
110110
kmip?: ClientEncryptionTlsOptions;
111111
local?: ClientEncryptionTlsOptions;
112112
azure?: ClientEncryptionTlsOptions;
113+
114+
[key: string]: ClientEncryptionTlsOptions | undefined;
113115
};
114116

115117
/**
@@ -319,7 +321,7 @@ export class StateMachine {
319321

320322
const tlsOptions = this.options.tlsOptions;
321323
if (tlsOptions) {
322-
const kmsProvider = request.kmsProvider as ClientEncryptionDataKeyProvider;
324+
const kmsProvider = request.kmsProvider;
323325
const providerTlsOptions = tlsOptions[kmsProvider];
324326
if (providerTlsOptions) {
325327
const error = this.validateTlsOptions(kmsProvider, providerTlsOptions);

src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,13 @@ export {
238238
} from './client-side-encryption/errors';
239239
export type { MongocryptdManager } from './client-side-encryption/mongocryptd_manager';
240240
export type {
241+
AWSKMSProviderConfiguration,
242+
AzureKMSProviderConfiguration,
241243
ClientEncryptionDataKeyProvider,
242-
KMSProviders
244+
GCPKMSProviderConfiguration,
245+
KMIPKMSProviderConfiguration,
246+
KMSProviders,
247+
LocalKMSProviderConfiguration
243248
} from './client-side-encryption/providers/index';
244249
export type {
245250
ClientEncryptionTlsOptions,

0 commit comments

Comments
 (0)