RUBY-3524 Add option to configure DEK cache lifetime - #3098
Merged
comandeo-mongo merged 1 commit intoJul 30, 2026
Conversation
Adds a key_expiration_ms option to both auto_encryption_options and ClientEncryption, wired to libmongocrypt's mongocrypt_setopt_key_expiration. A value of 0 means the data encryption key cache never expires; when the option is not given, libmongocrypt's 60000 ms default applies. libmongocrypt has exported this setopt since 1.12.0 and the driver already requires 1.20.0, so no version bump is needed.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds support for configuring libmongocrypt’s decrypted data encryption key (DEK) cache lifetime via a new :key_expiration_ms option, enabling applications using CSFLE to reduce KMS traffic under heavy load.
Changes:
- Adds an FFI binding and
Mongo::Crypt::Handleplumbing to setmongocrypt_setopt_key_expirationbeforemongocrypt_init. - Plumbs
:key_expiration_msthrough auto-encryption and explicitClientEncryptionAPIs, with associated documentation updates. - Adds coverage via a new unified spec fixture and targeted RSpec validation/pass-through tests.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| spec/spec_tests/data/client_side_encryption/unified/keyCache.yml | Adds unified test verifying DEK cache expiration behavior. |
| spec/runners/unified/test.rb | Plumbs keyExpirationMS from unified clientEncryptionOpts into driver options. |
| spec/mongo/crypt/handle_spec.rb | Adds RSpec coverage for :key_expiration_ms validation and nil/0 behavior. |
| lib/mongo/crypt/handle.rb | Validates and applies :key_expiration_ms via binding prior to mongocrypt_init. |
| lib/mongo/crypt/explicit_encrypter.rb | Accepts and forwards key_expiration_ms to Mongo::Crypt::Handle. |
| lib/mongo/crypt/binding.rb | Binds mongocrypt_setopt_key_expiration and exposes a checked wrapper. |
| lib/mongo/crypt/auto_encrypter.rb | Forwards :key_expiration_ms from auto-encryption options into the handle. |
| lib/mongo/client.rb | Documents :key_expiration_ms under :auto_encryption_options. |
| lib/mongo/client_encryption.rb | Documents and forwards :key_expiration_ms through ClientEncryption to explicit encrypter. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+45
to
+48
| # @option options [ Integer ] :key_expiration_ms The lifetime of the data | ||
| # encryption key cache, in milliseconds. Must be a non-negative integer. | ||
| # An explicit value of 0 means the cache never expires. The default is | ||
| # 60000. |
Comment on lines
+210
to
+216
| def set_key_expiration | ||
| unless @key_expiration_ms.is_a?(Integer) && !@key_expiration_ms.negative? | ||
| raise ArgumentError.new( | ||
| "#{@key_expiration_ms} is an invalid key_expiration_ms value; " \ | ||
| 'must be a non-negative Integer or nil' | ||
| ) | ||
| end |
jamis
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RUBY-3524
Adds a
key_expiration_msoption that controls how long libmongocrypt cachesdecrypted data encryption keys. Increasing it reduces the rate of KMS requests
under heavy load, which is the problem DRIVERS-2781
was filed for.
The option is accepted in two places, per the
client-side-encryption spec
(
AutoEncryptionOptsandClientEncryptionOpts, bothOptional<Uint64>,default 60000, 0 meaning "never expire"):
When the option is not given, no setopt call is made and libmongocrypt's
60000 ms default applies. This matters because 0 is a meaningful value, so
"unset" cannot be collapsed into 0.
mongocrypt_setopt_key_expirationhas been exported since libmongocrypt1.12.0 and
MIN_LIBMONGOCRYPT_VERSIONis already 1.20.0, so no version bumpis needed.
Changes
Option plumbing:
lib/mongo/crypt/binding.rb— bindmongocrypt_setopt_key_expirationand add asetopt_key_expirationwrapper that raisesMongo::Error::CryptErroron failurelib/mongo/crypt/handle.rb— accept:key_expiration_ms, validate it, and set it beforemongocrypt_initlib/mongo/crypt/auto_encrypter.rb— forward the option fromauto_encryption_optionslib/mongo/crypt/explicit_encrypter.rb,lib/mongo/client_encryption.rb— forward the option fromClientEncryptionDocumentation:
lib/mongo/client.rb— document:key_expiration_msunder:auto_encryption_optionsTests:
spec/spec_tests/data/client_side_encryption/unified/keyCache.yml— spec fixture, copied unmodified fromspecificationsspec/runners/unified/test.rb— readkeyExpirationMSfromclientEncryptionOptsspec/mongo/crypt/handle_spec.rb— validation and pass-through cases the unified format cannot expressA non-
Integeror negative value raisesArgumentError. This is stricterthan the driver's
timeout_ms(which only rejects negatives) but matches theexisting validation style in
Handleand avoids a confusing FFI error whenmarshalling to
uint64.