@@ -540,35 +540,35 @@ automatic credentials results in a runtime error from [libmongocrypt](#libmongoc
540
540
> [!NOTE]
541
541
> Drivers MUST NOT eagerly fill an empty KMS options property.
542
542
543
- Once requested, drivers MUST create a new [KMSProviders](#kmsproviders) ` $P$` according to the following process:
543
+ Once requested, drivers MUST create a new [KMSProviders](#kmsproviders) $P$ according to the following process:
544
544
545
- 1. Let ` $K$` be the [kmsProviders](#kmsproviders) value provided by the user as part of the original
545
+ 1. Let $K$ be the [kmsProviders](#kmsproviders) value provided by the user as part of the original
546
546
[ClientEncryptionOpts](#ClientEncryptionOpts) or [AutoEncryptionOpts](#AutoEncryptionOpts).
547
- 2. Initialize ` $P$` to an empty [KMSProviders](#kmsproviders) object.
548
- 3. If ` $K$` contains an `aws` property, and that property is an empty map:
549
- 1. Attempt to obtain credentials ` $C$` from the environment using similar logic as is detailed in
547
+ 2. Initialize $P$ to an empty [KMSProviders](#kmsproviders) object.
548
+ 3. If $K$ contains an `aws` property, and that property is an empty map:
549
+ 1. Attempt to obtain credentials $C$ from the environment using similar logic as is detailed in
550
550
[the obtaining-AWS-credentials section from the Driver Authentication specification](../auth/auth.md#obtaining-credentials),
551
551
but ignoring the case of loading the credentials from a URI
552
- 2. If credentials ` $C$` were successfully loaded, create a new [AWSKMSOptions](#AWSKMSOptions) map from ` $C$` and
553
- insert that map onto ` $P$` as the `aws` property.
554
- 4. If ` $K$` contains an `gcp` property, and that property is an empty map:
555
- 1. Attempt to obtain credentials ` $C$` from the environment logic as is detailed in
552
+ 2. If credentials $C$ were successfully loaded, create a new [AWSKMSOptions](#AWSKMSOptions) map from $C$ and insert
553
+ that map onto $P$ as the `aws` property.
554
+ 4. If $K$ contains an `gcp` property, and that property is an empty map:
555
+ 1. Attempt to obtain credentials $C$ from the environment logic as is detailed in
556
556
[Obtaining GCP Credentials](#obtaining-gcp-credentials).
557
- 2. If credentials ` $C$` were successfully loaded, create a new [GCPKMSOptions](#GCPKMSOptions) map from ` $C$` and
558
- insert that map onto ` $P$` as the `gcp` property.
559
- 5. If ` $K$` contains an `azure` property, and that property is an empty map:
557
+ 2. If credentials $C$ were successfully loaded, create a new [GCPKMSOptions](#GCPKMSOptions) map from $C$ and insert
558
+ that map onto $P$ as the `gcp` property.
559
+ 5. If $K$ contains an `azure` property, and that property is an empty map:
560
560
1. If there is a `cachedAzureAccessToken` AND the duration until `azureAccessTokenExpireTime` is greater than one
561
- minute, insert `cachedAzureAccessToken` as the `azure` property on ` $P$` .
561
+ minute, insert `cachedAzureAccessToken` as the `azure` property on $P$.
562
562
2. Otherwise:
563
- 1. Let ` $t_0$` be the current time.
564
- 2. Attempt to obtain an Azure VM Managed Identity Access Token ` $T$` as detailed in
563
+ 1. Let $t_0$ be the current time.
564
+ 2. Attempt to obtain an Azure VM Managed Identity Access Token $T$ as detailed in
565
565
[Obtaining an Access Token for Azure Key Vault](#obtaining-an-access-token-for-azure-key-vault).
566
- 3. If a token ` $T$` with expire duration ` $d\_{exp}$` were obtained successfully, create a new
567
- [AzureAccessToken](#AzureAccessToken) object with ` $T$` as the `accessToken` property. Insert that
568
- [AzureAccessToken](#AzureAccessToken) object into ` $P$` as the `azure` property. Record the generated
566
+ 3. If a token $T$ with expire duration $d\_{exp}$ were obtained successfully, create a new
567
+ [AzureAccessToken](#AzureAccessToken) object with $T$ as the `accessToken` property. Insert that
568
+ [AzureAccessToken](#AzureAccessToken) object into $P$ as the `azure` property. Record the generated
569
569
[AzureAccessToken](#AzureAccessToken) in `cachedAzureAccessToken`. Record the `azureAccessTokenExpireTime` as
570
- ` $t_0 + d\_{exp}$` .
571
- 6. Return ` $P$` as the additional KMS providers to [libmongocrypt](#libmongocrypt).
570
+ $t_0 + d\_{exp}$.
571
+ 6. Return $P$ as the additional KMS providers to [libmongocrypt](#libmongocrypt).
572
572
573
573
<span id="obtaining-gcp-credentials" />
574
574
@@ -601,37 +601,37 @@ the VM, an identity can be used by obtaining an access token via HTTP from the *
601
601
602
602
The below steps should be taken:
603
603
604
- 01. Let ` $U$` be a new URL, initialized from the URL string `"http://169.254.169.254/metadata/identity/oauth2/token"`
604
+ 01. Let $U$ be a new URL, initialized from the URL string `"http://169.254.169.254/metadata/identity/oauth2/token"`
605
605
606
- 02. Add a query parameter `api-version=2018-02-01` to ` $U$` .
606
+ 02. Add a query parameter `api-version=2018-02-01` to $U$.
607
607
608
- 03. Add a query parameter `resource=https://vault.azure.net/` to ` $U$` .
608
+ 03. Add a query parameter `resource=https://vault.azure.net/` to $U$.
609
609
610
- 04. Prepare an HTTP GET request ` $Req$` based on ` $U$` .
610
+ 04. Prepare an HTTP GET request $Req$ based on $U$.
611
611
612
612
> [!NOTE]
613
- > All query parameters on ` $U$` should be appropriately percent-encoded
613
+ > All query parameters on $U$ should be appropriately percent-encoded
614
614
615
- 05. Add HTTP headers `Metadata: true` and `Accept: application/json` to ` $Req$` .
615
+ 05. Add HTTP headers `Metadata: true` and `Accept: application/json` to $Req$.
616
616
617
- 06. Issue ` $Req$` to the Azure IMDS server `169.254.169.254:80`. Let ` $Resp$` be the response from the server. If the
618
- HTTP response is not completely received within ten seconds, consider the request to have timed out, and return an
619
- error instead of an access token.
617
+ 06. Issue $Req$ to the Azure IMDS server `169.254.169.254:80`. Let $Resp$ be the response from the server. If the HTTP
618
+ response is not completely received within ten seconds, consider the request to have timed out, and return an error
619
+ instead of an access token.
620
620
621
- 07. If `$Resp_ {status} ≠ 200$` , obtaining the access token has failed, and the HTTP response body of ` $Resp$` encodes
621
+ 07. If $Resp\_ {status} ≠ 200$, obtaining the access token has failed, and the HTTP response body of $Resp$ encodes
622
622
information about the error that occurred. Return an error including the HTTP response body instead of an access
623
623
token.
624
624
625
- 08. Otherwise, let ` $J$` be the JSON document encoded in the HTTP response body of ` $Resp$` .
625
+ 08. Otherwise, let $J$ be the JSON document encoded in the HTTP response body of $Resp$.
626
626
627
- 09. The result access token ` $T$` is given as the `access_token` string property of ` $J$` . Return ` $T$` as the resulting
627
+ 09. The result access token $T$ is given as the `access_token` string property of $J$. Return $T$ as the resulting
628
628
access token.
629
629
630
- 10. The resulting "expires in" duration `$d_ {exp}$` is a count of seconds given as an ASCII-encoded integer string
631
- `expires_in` property of ` $J$` .
630
+ 10. The resulting "expires in" duration $d\_ {exp}$ is a count of seconds given as an ASCII-encoded integer string
631
+ `expires_in` property of $J$.
632
632
633
633
> [!NOTE]
634
- > If JSON decoding of ` $Resp$` fails, or the `access_token` property is absent from ` $J$` , this is a protocol error from
634
+ > If JSON decoding of $Resp$ fails, or the `access_token` property is absent from $J$, this is a protocol error from
635
635
> IMDS. Indicate this error to the requester of the access token.
636
636
637
637
> [!NOTE]
@@ -809,19 +809,19 @@ A collection supporting Queryable Encryption requires an index and three additio
809
809
The convenience methods support the following lookup process for finding the `encryptedFields` associated with a
810
810
collection.
811
811
812
- Assume an exposition-only function ` $GetEncryptedFields(opts, collName, dbName, askDb)$` , where ` $opts$` is a set of
813
- options, ` $collName$` is the name of the collection, ` $dbName$` is the name of the database associated with that
814
- collection, and ` $askDb$` is a boolean value. The resulting `encryptedFields` ` $EF$` is found by:
812
+ Assume an exposition-only function $GetEncryptedFields(opts, collName, dbName, askDb)$, where $opts$ is a set of
813
+ options, $collName$ is the name of the collection, $dbName$ is the name of the database associated with that collection,
814
+ and $askDb$ is a boolean value. The resulting `encryptedFields` $EF$ is found by:
815
815
816
- 1. Let ` $QualName$` be the string formed by joining` $dbName$` and ` $collName$` with an ASCII dot `"."`.
817
- 2. If ` $opts$` contains an `"encryptedFields"` property, then ` $EF$` is the value of that property.
818
- 3. Otherwise, if `AutoEncryptionOptions.encryptedFieldsMap` contains an element named by ` $QualName$` , then ` $EF$` is
819
- the value of that element.
820
- 4. Otherwise, if ` $askDb$` is `true`:
816
+ 1. Let $QualName$ be the string formed by joining$dbName$ and $collName$ with an ASCII dot `"."`.
817
+ 2. If $opts$ contains an `"encryptedFields"` property, then $EF$ is the value of that property.
818
+ 3. Otherwise, if `AutoEncryptionOptions.encryptedFieldsMap` contains an element named by $QualName$, then $EF$ is the
819
+ value of that element.
820
+ 4. Otherwise, if $askDb$ is `true`:
821
821
1. Issue a `listCollections` command against the database named by $dbName$, filtered by `{name: <collName>}`. Let
822
- the result be the document ` $L$` .
823
- 2. If ` $L$` contains an `options` document element, and that element contains an `encryptedFields` document element,
824
- ` $EF$` is ` $L$` `["options"]["encryptedFields"]`.
822
+ the result be the document $L$.
823
+ 2. If $L$ contains an `options` document element, and that element contains an `encryptedFields` document element,
824
+ $EF$ is $L$ `["options"]["encryptedFields"]`.
825
825
3. Otherwise, $EF$ is *not-found*
826
826
5. Otherwise, $EF$ is considered *not-found*.
827
827
@@ -843,8 +843,8 @@ Drivers MUST support a BSON document option named `encryptedFields` for any
843
843
> Drivers MUST NOT document the `escCollection` and `ecocCollection` options.
844
844
845
845
For a helper function, `CreateCollection(collectionName, collectionOptions)` with the name of the database associated as
846
- ` $dbName$` , look up the encrypted fields `encryptedFields` for the collection as
847
- `$GetEncryptedFields(collectionOptions, collectionName, dbName, false)$` ([See here](#GetEncryptedFields)).
846
+ $dbName$, look up the encrypted fields `encryptedFields` for the collection as $GetEncryptedFields(collectionOptions,
847
+ collectionName, dbName, false)$ ([See here](#GetEncryptedFields)).
848
848
849
849
If a set of `encryptedFields` was found, then do the following operations. If any of the following operations error, the
850
850
remaining operations are not attempted:
@@ -867,33 +867,33 @@ remaining operations are not attempted:
867
867
868
868
#### Create Encrypted Collection Helper
869
869
870
- To support automatic generation of encryption data keys, a helper
871
- `$CreateEncryptedCollection(CE, database, collName, collOpts, kmsProvider, masterKey)$` is defined, where ` $CE$` is a
872
- [ClientEncryption](#clientencryption-1) object, ` $kmsProvider$` is a [KMSProvider](#KMSProvider) and ` $masterKey$` is
873
- equivalent to the `$masterKey$` defined in [DataKeyOpts](#datakeyopts). It has the following behavior:
874
-
875
- - If ` $collOpts$` contains an `"encryptedFields"` property, then ` $EF$` is the value of that property. Otherwise, report
876
- an error that there are no `encryptedFields` defined for the collection.
877
- - Let ` $EF'$` be a copy of ` $EF$` . Update ` $EF'$` in the following manner:
878
- - Let ` $Fields$` be the `"fields"` element within ` $EF'$` .
879
- - If ` $Fields$` is present and is an array value, then for each element ` $F$` of `Fields`:
880
- - If ` $F$` is not a document element, skip it.
881
- - Otherwise, if ` $F$` has a `"keyId"` named element ` $K$` and ` $K$` is a `null` value:
882
- - Create a [DataKeyOpts](#datakeyopts) named ` $dkOpts$` with the ` $masterKey$` argument.
883
- - Let ` $D$` be the result of `CE.createDataKey(kmsProvider, dkOpts)`.
884
- - If generating ` $D$` resulted in an error ` $E$` , the entire ` $CreateEncryptedCollection$` must now fail with
885
- error `$E$`. Return the partially-formed ` $EF'$` with the error so that the caller may know what datakeys have
886
- already been created by the helper.
887
- - Replace ` $K$` in ` $F$` with ` $D$` .
888
- - Create a new set of options ` $collOpts'$` duplicating ` $collOpts$` . Set the `"encryptedFields"` named element of
889
- ` $collOpts'$` to ` $EF'$` .
890
- - Invoke the `CreateCollection` helper as ` $CreateCollection(database, collName, collOpts')$` . Return the resulting
891
- collection and the generated ` $EF'$` . If an error occurred, return the resulting ` $EF$` with the error so that the
892
- caller may know what datakeys have already been created by the helper.
893
-
894
- Drivers MUST document that ` $createEncryptedCollection$` does not affect any auto encryption settings on existing
870
+ To support automatic generation of encryption data keys, a helper $CreateEncryptedCollection(CE, database, collName,
871
+ collOpts, kmsProvider, masterKey)$ is defined, where $CE$ is a [ClientEncryption](#clientencryption-1) object,
872
+ $kmsProvider$ is a [KMSProvider](#KMSProvider) and $masterKey$ is equivalent to the $masterKey$ defined in
873
+ [DataKeyOpts](#datakeyopts). It has the following behavior:
874
+
875
+ - If $collOpts$ contains an `"encryptedFields"` property, then $EF$ is the value of that property. Otherwise, report an
876
+ error that there are no `encryptedFields` defined for the collection.
877
+ - Let $EF'$ be a copy of $EF$. Update $EF'$ in the following manner:
878
+ - Let $Fields$ be the `"fields"` element within $EF'$.
879
+ - If $Fields$ is present and is an array value, then for each element $F$ of `Fields`:
880
+ - If $F$ is not a document element, skip it.
881
+ - Otherwise, if $F$ has a `"keyId"` named element $K$ and $K$ is a `null` value:
882
+ - Create a [DataKeyOpts](#datakeyopts) named $dkOpts$ with the $masterKey$ argument.
883
+ - Let $D$ be the result of `CE.createDataKey(kmsProvider, dkOpts)`.
884
+ - If generating $D$ resulted in an error $E$, the entire $CreateEncryptedCollection$ must now fail with error $E$.
885
+ Return the partially-formed $EF'$ with the error so that the caller may know what datakeys have already been
886
+ created by the helper.
887
+ - Replace $K$ in $F$ with $D$.
888
+ - Create a new set of options $collOpts'$ duplicating $collOpts$. Set the `"encryptedFields"` named element of
889
+ $collOpts'$ to $EF'$.
890
+ - Invoke the `CreateCollection` helper as $CreateCollection(database, collName, collOpts')$. Return the resulting
891
+ collection and the generated $EF'$. If an error occurred, return the resulting $EF$ with the error so that the caller
892
+ may know what datakeys have already been created by the helper.
893
+
894
+ Drivers MUST document that $createEncryptedCollection$ does not affect any auto encryption settings on existing
895
895
MongoClients that are already configured with auto encryption. Users must configure auto encryption after creating the
896
- encrypted collection with the ` $createEncryptedCollection$` helper.
896
+ encrypted collection with the $createEncryptedCollection$ helper.
897
897
898
898
#### Drop Collection Helper
899
899
@@ -912,9 +912,9 @@ Drivers MUST support a BSON document option named `encryptedFields` for any
912
912
>
913
913
> Drivers SHOULD NOT document the `escCollection` and `ecocCollection` options.
914
914
915
- For a helper function `DropCollection(dropOptions)` with associated collection named ` $collName$` and database named
916
- ` $dbName$` , look up the encrypted fields `encryptedFields` as
917
- `$GetEncryptedFields(dropOptions, collName, dbname, true)$` ([See here](#GetEncryptedFields)).
915
+ For a helper function `DropCollection(dropOptions)` with associated collection named $collName$ and database named
916
+ $dbName$, look up the encrypted fields `encryptedFields` as $GetEncryptedFields(dropOptions, collName, dbname, true)$
917
+ ([See here](#GetEncryptedFields)).
918
918
919
919
If a set of `encryptedFields` was found, then perform the following operations. If any of the following operations
920
920
error, the remaining operations are not attempted. A `namespace not found` error returned from the server (server error
0 commit comments