Skip to content

Commit 835e027

Browse files
committed
PYTHON-4580 Add key_expiration_ms option for DEK cache lifetime
1 parent f69e1f6 commit 835e027

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

pymongo/asynchronous/encryption.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ def _get_internal_client(
445445
bypass_encryption=opts._bypass_auto_encryption,
446446
encrypted_fields_map=encrypted_fields_map,
447447
bypass_query_analysis=opts._bypass_query_analysis,
448+
key_expiration_ms=opts._key_expiration_ms,
448449
),
449450
)
450451
self._closed = False
@@ -564,6 +565,7 @@ def __init__(
564565
key_vault_client: AsyncMongoClient[_DocumentTypeArg],
565566
codec_options: CodecOptions[_DocumentTypeArg],
566567
kms_tls_options: Optional[Mapping[str, Any]] = None,
568+
key_expiration_ms: Optional[int] = None,
567569
) -> None:
568570
"""Explicit client-side field level encryption.
569571
@@ -630,7 +632,12 @@ def __init__(
630632
Or to supply a client certificate::
631633
632634
kms_tls_options={'kmip': {'tlsCertificateKeyFile': 'client.pem'}}
635+
:param key_expiration_ms: The cache expiration time for data encryption keys.
636+
Defaults to ``None`` which defers to libmongocrypt's default which is currently 60000.
637+
Set to 0 to disable key expiration.
633638
639+
.. versionchanged:: 4.12
640+
Added the `key_expiration_ms` parameter.
634641
.. versionchanged:: 4.0
635642
Added the `kms_tls_options` parameter and the "kmip" KMS provider.
636643
@@ -666,14 +673,19 @@ def __init__(
666673
key_vault_coll = key_vault_client[db][coll]
667674

668675
opts = AutoEncryptionOpts(
669-
kms_providers, key_vault_namespace, kms_tls_options=kms_tls_options
676+
kms_providers,
677+
key_vault_namespace,
678+
kms_tls_options=kms_tls_options,
679+
key_expiration_ms=key_expiration_ms,
670680
)
671681
self._io_callbacks: Optional[_EncryptionIO] = _EncryptionIO(
672682
None, key_vault_coll, None, opts
673683
)
674684
self._encryption = AsyncExplicitEncrypter(
675685
self._io_callbacks,
676-
_create_mongocrypt_options(kms_providers=kms_providers, schema_map=None),
686+
_create_mongocrypt_options(
687+
kms_providers=kms_providers, schema_map=None, key_expiration_ms=key_expiration_ms
688+
),
677689
)
678690
# Use the same key vault collection as the callback.
679691
assert self._io_callbacks.key_vault_coll is not None
@@ -700,6 +712,7 @@ async def create_encrypted_collection(
700712
creation. :class:`~pymongo.errors.EncryptionError` will be
701713
raised if the collection already exists.
702714
715+
:param database: the database to create the collection
703716
:param name: the name of the collection to create
704717
:param encrypted_fields: Document that describes the encrypted fields for
705718
Queryable Encryption. The "keyId" may be set to ``None`` to auto-generate the data keys. For example:

pymongo/encryption_options.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def __init__(
5757
crypt_shared_lib_required: bool = False,
5858
bypass_query_analysis: bool = False,
5959
encrypted_fields_map: Optional[Mapping[str, Any]] = None,
60+
key_expiration_ms: Optional[int] = None,
6061
) -> None:
6162
"""Options to configure automatic client-side field level encryption.
6263
@@ -191,9 +192,14 @@ def __init__(
191192
]
192193
}
193194
}
195+
:param key_expiration_ms: The cache expiration time for data encryption keys.
196+
Defaults to ``None`` which defers to libmongocrypt's default which is currently 60000.
197+
Set to 0 to disable key expiration.
194198
199+
.. versionchanged:: 4.12
200+
Added the `key_expiration_ms` parameter.
195201
.. versionchanged:: 4.2
196-
Added `encrypted_fields_map` `crypt_shared_lib_path`, `crypt_shared_lib_required`,
202+
Added the `encrypted_fields_map`, `crypt_shared_lib_path`, `crypt_shared_lib_required`,
197203
and `bypass_query_analysis` parameters.
198204
199205
.. versionchanged:: 4.0
@@ -210,7 +216,6 @@ def __init__(
210216
if encrypted_fields_map:
211217
validate_is_mapping("encrypted_fields_map", encrypted_fields_map)
212218
self._encrypted_fields_map = encrypted_fields_map
213-
self._bypass_query_analysis = bypass_query_analysis
214219
self._crypt_shared_lib_path = crypt_shared_lib_path
215220
self._crypt_shared_lib_required = crypt_shared_lib_required
216221
self._kms_providers = kms_providers
@@ -233,6 +238,7 @@ def __init__(
233238
# Maps KMS provider name to a SSLContext.
234239
self._kms_ssl_contexts = _parse_kms_tls_options(kms_tls_options)
235240
self._bypass_query_analysis = bypass_query_analysis
241+
self._key_expiration_ms = key_expiration_ms
236242

237243

238244
class RangeOpts:

pymongo/synchronous/encryption.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ def _get_internal_client(
442442
bypass_encryption=opts._bypass_auto_encryption,
443443
encrypted_fields_map=encrypted_fields_map,
444444
bypass_query_analysis=opts._bypass_query_analysis,
445+
key_expiration_ms=opts._key_expiration_ms,
445446
),
446447
)
447448
self._closed = False
@@ -561,6 +562,7 @@ def __init__(
561562
key_vault_client: MongoClient[_DocumentTypeArg],
562563
codec_options: CodecOptions[_DocumentTypeArg],
563564
kms_tls_options: Optional[Mapping[str, Any]] = None,
565+
key_expiration_ms: Optional[int] = None,
564566
) -> None:
565567
"""Explicit client-side field level encryption.
566568
@@ -627,7 +629,12 @@ def __init__(
627629
Or to supply a client certificate::
628630
629631
kms_tls_options={'kmip': {'tlsCertificateKeyFile': 'client.pem'}}
632+
:param key_expiration_ms: The cache expiration time for data encryption keys.
633+
Defaults to ``None`` which defers to libmongocrypt's default which is currently 60000.
634+
Set to 0 to disable key expiration.
630635
636+
.. versionchanged:: 4.12
637+
Added the `key_expiration_ms` parameter.
631638
.. versionchanged:: 4.0
632639
Added the `kms_tls_options` parameter and the "kmip" KMS provider.
633640
@@ -659,14 +666,19 @@ def __init__(
659666
key_vault_coll = key_vault_client[db][coll]
660667

661668
opts = AutoEncryptionOpts(
662-
kms_providers, key_vault_namespace, kms_tls_options=kms_tls_options
669+
kms_providers,
670+
key_vault_namespace,
671+
kms_tls_options=kms_tls_options,
672+
key_expiration_ms=key_expiration_ms,
663673
)
664674
self._io_callbacks: Optional[_EncryptionIO] = _EncryptionIO(
665675
None, key_vault_coll, None, opts
666676
)
667677
self._encryption = ExplicitEncrypter(
668678
self._io_callbacks,
669-
_create_mongocrypt_options(kms_providers=kms_providers, schema_map=None),
679+
_create_mongocrypt_options(
680+
kms_providers=kms_providers, schema_map=None, key_expiration_ms=key_expiration_ms
681+
),
670682
)
671683
# Use the same key vault collection as the callback.
672684
assert self._io_callbacks.key_vault_coll is not None
@@ -693,6 +705,7 @@ def create_encrypted_collection(
693705
creation. :class:`~pymongo.errors.EncryptionError` will be
694706
raised if the collection already exists.
695707
708+
:param database: the database to create the collection
696709
:param name: the name of the collection to create
697710
:param encrypted_fields: Document that describes the encrypted fields for
698711
Queryable Encryption. The "keyId" may be set to ``None`` to auto-generate the data keys. For example:

0 commit comments

Comments
 (0)