@@ -10,8 +10,8 @@ Client Side Encryption
10
10
:Status: Accepted
11
11
:Type: Standards
12
12
:Minimum Server Version: 4.2 (CSFLE), 6.0 (Queryable Encryption)
13
- :Last Modified: 2022-09-09
14
- :Version: 1.11.1
13
+ :Last Modified: 2022-09-26
14
+ :Version: 1.12.0
15
15
16
16
.. _lmc-c-api : https://github.com/mongodb/libmongocrypt/blob/master/src/mongocrypt.h.in
17
17
@@ -26,6 +26,8 @@ Client Side Encryption
26
26
.. |true | replace :: :ts: `true `
27
27
.. |false | replace :: :ts: `false `
28
28
29
+ .. |-- | unicode :: 0x2014 .. em dash
30
+
29
31
.. contents ::
30
32
31
33
--------
@@ -324,6 +326,8 @@ specified as a BSON binary with subtype 0x04 as described in
324
326
MongoClient Changes
325
327
-------------------
326
328
329
+ .. _MongoClient :
330
+
327
331
.. code :: typescript
328
332
329
333
class MongoClient {
@@ -335,6 +339,10 @@ MongoClient Changes
335
339
private MongoClient keyvault_client; // Client used to run find on the key vault collection. This is either an external MongoClient, the parent MongoClient, or internal_client.
336
340
private MongoClient metadata_client; // Client used to run listCollections. This is either the parent MongoClient or internal_client.
337
341
private Optional < MongoClient > internal_client; // An internal MongoClient. Created if no external keyVaultClient was set, or if a metadataClient is needed
342
+
343
+ // Exposition-only, used for caching automatic Azure credentials
344
+ private cachedAzureAccessToken? : AzureAccessToken ;
345
+ private azureAccessTokenExpireTime? : PointInTime ;
338
346
}
339
347
340
348
.. _AutoEncryptionOpts :
@@ -461,6 +469,7 @@ See `What's the deal with metadataClient, keyVaultClient, and the internal clien
461
469
.. _KMSProviderName :
462
470
.. _AWSKMSOptions :
463
471
.. _GCPKMSOptions :
472
+ .. _AzureAccessToken :
464
473
465
474
kmsProviders
466
475
^^^^^^^^^^^^
@@ -480,9 +489,9 @@ accept arbitrary strings at runtime for forward-compatibility.
480
489
.. code :: typescript
481
490
482
491
interface KMSProviders {
483
- aws? : AWSKMSOptions | { /* Empty. (See "Automatic Credentials") */ };
484
- azure? : AzureKMSOptions ;
485
- gcp? : GCPKMSOptions | { /* Empty. (See "Automatic Credentials") */ };
492
+ aws? : AWSKMSOptions | { /* Empty (See "Automatic Credentials") */ };
493
+ azure? : AzureKMSOptions | { /* Empty (See "Automatic Credentials") */ } ;
494
+ gcp? : GCPKMSOptions | { /* Empty (See "Automatic Credentials") */ };
486
495
local? : LocalKMSOptions ;
487
496
kmip? : KMIPKMSOptions ;
488
497
};
@@ -497,13 +506,19 @@ accept arbitrary strings at runtime for forward-compatibility.
497
506
sessionToken? : string ; // Required for temporary AWS credentials.
498
507
};
499
508
500
- interface AzureKMSOptions {
509
+ type AzureKMSOptions = AzureKMSCredentials | AzureAccessToken ;
510
+
511
+ interface AzureKMSCredentials {
501
512
tenantId: string ;
502
513
clientId: string ;
503
514
clientSecret: string ;
504
515
identityPlatformEndpoint? : string ; // Defaults to login.microsoftonline.com
505
516
};
506
517
518
+ interface AzureAccessToken {
519
+ accessToken: string ;
520
+ };
521
+
507
522
type GCPKMSOptions = GCPKMSCredentials | GCPKMSAccessToken
508
523
509
524
interface GCPKMSCredentials {
@@ -530,51 +545,67 @@ Automatic Credentials
530
545
531
546
.. versionadded :: 1.9.0 2022/06/22
532
547
533
- If the ``aws `` or ``gcp `` provider properties of a KMSProviders _ are present and
534
- are an empty map/object, the driver MUST be able to populate an AWSKMSOptions _ or
535
- GCPKMSOptions _ object on-demand if-and-only-if AWS or GCP credentials are
536
- needed.
548
+ Certain values of KMSProviders _ indicate a request by the user that the
549
+ associated KMS providers should be populated lazily on-demand. The driver MUST
550
+ be able to populate the respective options object on-demand if-and-only-if such
551
+ respective credentials are needed. The request for KMS credentials will be
552
+ indicated by libmongocrypt _ only once they are needed.
553
+
554
+ When such a state is detected, libmongocrypt _ will call back to the driver by
555
+ entering the ``MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS `` state, upon which the
556
+ driver should fill in the KMS options automatically.
557
+
558
+ .. note :: Drivers MUST NOT eagerly fill an empty KMS options property.
537
559
538
- .. note :: Drivers MUST NOT eagerly fill an empty ``aws`` or ``gcp`` map property.
560
+ .. default-role :: math
539
561
540
- libmongocrypt _ will interpret an empty KMSProviders _ map properties as a request
541
- by the user to lazily load the credentials for the respective `KMS provider `_.
542
- libmongocrypt _ will call back to the driver to fill an empty KMS provider
543
- property only once the associated credentials are needed by entering
544
- the ``MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS `` state.
562
+ Once requested, drivers MUST create a new KMSProviders _ `P ` according to the
563
+ following process:
545
564
546
- Once requested, drivers MUST create a new KMSProviders _ :math: `P` according to
547
- the following process:
565
+ 1. Let `K ` be the kmsProviders _ value provided by the user as part of the
566
+ original ClientEncryptionOpts _ or AutoEncryptionOpts _.
567
+ 2. Initialize `P ` to an empty KMSProviders _ object.
568
+ 3. If `K ` contains an ``aws `` property, and that property is an empty map:
548
569
549
- 1. Initialize :math: `P` to an empty KMSProviders _ object.
550
- 2. If the user-provided kmsProviders _ (from ClientEncryptionOpts _ or
551
- AutoEncryptionOpts _) contains an ``aws `` property, and that property is an
552
- empty map:
570
+ 1. Attempt to obtain credentials `C ` from the environment using similar logic
571
+ as is detailed in `the obtaining-AWS-credentials section from the Driver
572
+ Authentication specification `__, but ignoring the case of loading the
573
+ credentials from a URI
574
+ 2. If credentials `C ` were successfully loaded, create a new AWSKMSOptions _
575
+ map from `C ` and insert that map onto `P ` as the ``aws `` property.
553
576
554
- 1. Attempt to obtain credentials :math: `C` from the environment using similar
555
- logic as is detailed in `the obtaining-AWS-credentials section from the
556
- Driver Authentication specification `__, but ignoring the case of loading
557
- the credentials from a URI
558
- 2. If credentials :math: `C` were successfully loaded, create a new
559
- AWSKMSOptions _ map from :math: `C` and insert that map onto :math: `P` as
560
- the ``aws `` property.
577
+ 4. If `K ` contains an ``gcp `` property, and that property is an empty map:
561
578
562
- 3. If the user-provided kmsProviders _ (from ClientEncryptionOpts _ or
563
- AutoEncryptionOpts _) contains an ``gcp `` property, and that property is an
564
- empty map:
579
+ 1. Attempt to obtain credentials `C ` from the environment logic as is
580
+ detailed in `Obtaining GCP Credentials `_.
581
+ 2. If credentials `C ` were successfully loaded, create a new GCPKMSOptions _
582
+ map from `C ` and insert that map onto `P ` as the ``gcp `` property.
565
583
566
- 1. Attempt to obtain credentials :math: `C` from the environment
567
- logic as is detailed in `Obtaining GCP Credentials `_.
568
- 2. If credentials :math: `C` were successfully loaded, create a new
569
- GCPKMSOptions _ map from :math: `C` and insert that map onto :math: `P` as
570
- the ``gcp `` property.
584
+ 5. If `K ` contains an ``azure `` property, and that property is an empty map:
571
585
572
- 4. Return :math: `P` as the additional KMS providers to libmongocrypt _.
586
+ 1. If the current MongoClient _ has a ``cachedAzureAccessToken `` AND the
587
+ duration until ``azureAccessTokenExpireTime `` is greater than one minute,
588
+ insert ``cachedAzureAccessToken `` as the ``azure `` property on `P `.
589
+ 2. Otherwise:
590
+
591
+ 1. Let `t_0 ` be the current time.
592
+ 2. Attempt to obtain an Azure VM Managed Identity Access Token `T ` as
593
+ detailed in `Obtaining an Access Token for Azure Key Vault `_.
594
+ 3. If a token `T ` with expire duration `d_{exp} ` were obtained
595
+ successfully, create a new AzureAccessToken _ object with `T ` as the
596
+ ``accessToken `` property. Insert that AzureAccessToken _ object into `P `
597
+ as the ``azure `` property. Record the generated AzureAccessToken _ in
598
+ ``cachedAzureAccessToken ``. Record the ``azureAccessTokenExpireTime ``
599
+ as `t_0 + d_{exp} `.
600
+
601
+ 6. Return `P ` as the additional KMS providers to libmongocrypt _.
573
602
574
603
__ ../auth/auth.html#obtaining-credentials
575
604
605
+ .. default-role :: literal
606
+
576
607
Obtaining GCP Credentials
577
- ^^^^^^^^^^^^^^^^^^^^^^^^^
608
+ `````````````````````````
578
609
579
610
.. versionadded :: 1.11.0 2022/07/20
580
611
@@ -596,6 +627,61 @@ message.
596
627
597
628
Return "access_token" as the credential.
598
629
630
+
631
+ Obtaining an Access Token for Azure Key Vault
632
+ `````````````````````````````````````````````
633
+
634
+ .. versionadded :: 1.12.0 2022/08/30
635
+
636
+ Virtual machines running on the Azure platform have one or more *Managed
637
+ Identities * associated with them. From within the VM, an identity can be used by
638
+ obtaining an access token via HTTP from the *Azure Instance Metadata Service *
639
+ (IMDS). `See this documentation for more information `__
640
+
641
+ __ https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
642
+
643
+ .. default-role :: math
644
+
645
+ The below steps should be taken:
646
+
647
+ 1. Let `U ` be a new URL, initialized from the URL string
648
+ :ts: `"http://169.254.169.254/metadata/identity/oauth2/token" `
649
+ 2. Add a query parameter ``api-version=2018-02-01 `` to `U `.
650
+ 3. Add a query parameter ``resource=http://vault.azure.com/ `` to `U `.
651
+ 4. Prepare an HTTP GET request `Req ` based on `U `.
652
+
653
+ .. note :: All query parameters on `U` should be appropriately percent-encoded
654
+
655
+ 5. Add HTTP headers ``Metadata: true `` and ``Accept: application/json `` to
656
+ `Req `.
657
+ 6. Issue `Req ` to the Azure IMDS server ``168.254.169.254:80 ``. Let `Resp ` be
658
+ the response from the server.
659
+ 7. If `Resp_{status} ≠ 200 `, obtaining the access token has failed, and the
660
+ HTTP response body of `Resp ` encodes information about the error that
661
+ occurred. Return an error instead of an access token.
662
+ 8. Otherwise, let `J ` be the JSON document encoded in the HTTP response body
663
+ of `Resp `.
664
+ 9. The result access token `T ` is given as the ``access_token `` string property
665
+ of `J `. Return `T ` as the resulting access token.
666
+ 10. The resulting "expires in" duration `d_{exp} ` is a count of seconds given as an
667
+ ASCII-encoded integer string ``expires_in `` property of `J `.
668
+
669
+ .. note ::
670
+
671
+ If JSON decoding of `Resp ` fails, or the ``access_token `` property is absent
672
+ from `J `, this is a protocol error from IMDS. Indicate this error to the
673
+ requester of the access token.
674
+
675
+ .. note ::
676
+
677
+ If an Azure VM has more than one managed identity, requesting an access token
678
+ requires additional query parameters to disambiguate the request. For
679
+ simplicity, these parameters are omitted, and only VMs that have a single
680
+ managed identity are supported.
681
+
682
+ .. default-role :: literal
683
+
684
+
599
685
KMS provider TLS options
600
686
````````````````````````
601
687
@@ -2435,7 +2521,7 @@ Changelog
2435
2521
:align: left
2436
2522
2437
2523
Date, Description
2438
-
2524
+ 22 - 0 9 - 26 , Add behavior for automatic Azure KeyVault credentials for `` kmsProviders `` .
2439
2525
22 - 09 - 09 , Prohibit `` rewrapManyDataKey`` with libmongocrypt <= 1.5 .1.
2440
2526
22 - 07 - 20 , Add behavior for automatic GCP credential loading in `` kmsProviders`` .
2441
2527
22 - 06 - 30 , Add behavior for automatic AWS credential loading in `` kmsProviders`` .
@@ -2448,7 +2534,7 @@ Changelog
2448
2534
22 - 06 - 08 , Add `` Queryable Encryption`` to abstract.
2449
2535
22 - 06 - 02 , Rename `` FLE 2 `` to `` Queryable Encryption``
2450
2536
22 - 05 - 31 , Rename `` csfle`` to `` crypt_shared``
2451
- 22 - 05 - 27 , Define ECC , ECOC , and ESC acronyms within encryptedFields
2537
+ 22 - 05 - 27 , " Define ECC, ECOC, and ESC acronyms within encryptedFields"
2452
2538
22 - 05 - 26 , Clarify how `` encryptedFields`` interacts with `` create`` and `` drop`` commands
2453
2539
22 - 05 - 24 , Add key management API functions
2454
2540
22 - 05 - 18 , Add createKey and rewrapManyDataKey
0 commit comments