From d55fd69b7be9d2e6ed24d8413acfa1e430877ded Mon Sep 17 00:00:00 2001 From: jnjpng Date: Tue, 6 Jan 2026 18:19:04 -0800 Subject: [PATCH] chore: add comment and test for changing PBKDF2 iteration count (#8366) base --- letta/helpers/crypto_utils.py | 4 +++- tests/test_crypto_utils.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/letta/helpers/crypto_utils.py b/letta/helpers/crypto_utils.py index 22400711..a38f60b5 100644 --- a/letta/helpers/crypto_utils.py +++ b/letta/helpers/crypto_utils.py @@ -50,7 +50,9 @@ class CryptoUtils: # Salt size for key derivation SALT_SIZE = 16 - # Number of PBKDF2 iterations - matches previous cryptography library setting + # WARNING: DO NOT CHANGE THIS VALUE UNLESS YOU ARE SURE WHAT YOU ARE DOING + # EXISTING ENCRYPTED SECRETS MUST BE DECRYPTED WITH THE SAME ITERATIONS + # Number of PBKDF2 iterations PBKDF2_ITERATIONS = 100000 @classmethod diff --git a/tests/test_crypto_utils.py b/tests/test_crypto_utils.py index a804b708..6ceabdd5 100644 --- a/tests/test_crypto_utils.py +++ b/tests/test_crypto_utils.py @@ -353,6 +353,25 @@ class TestBackwardsCompatibility: # Test key and known encrypted values generated with the cryptography library MOCK_KEY = "test-master-key-1234567890abcdef" + def test_pbkdf2_iterations_not_changed(self): + """ + CRITICAL: Verify that PBKDF2_ITERATIONS has not been changed from 100000. + + WARNING: DO NOT CHANGE THIS VALUE! + Changing the iteration count will break decryption of ALL existing + encrypted secrets in the database. If you need to change this value, + you MUST first migrate all existing encrypted values. + + This test exists to prevent accidental changes that would cause + production outages due to inability to decrypt existing secrets. + """ + assert CryptoUtils.PBKDF2_ITERATIONS == 100000, ( + "CRITICAL: PBKDF2_ITERATIONS has been changed from 100000! " + "This will BREAK DECRYPTION of all existing encrypted secrets in the database. " + "If you intentionally need to change this, you must first migrate all existing " + "encrypted values. Revert this change immediately if unintentional." + ) + def test_hashlib_pbkdf2_matches_cryptography_pbkdf2(self): """ Verify that hashlib.pbkdf2_hmac produces identical output to