mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-16 04:29:31 +00:00
fix(proxy): keep long first-write config values without PyNaCl instead of storing null
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
a7c350faee
commit
a6a968b9fb
3 changed files with 15 additions and 3 deletions
|
|
@ -269,6 +269,15 @@ def legacy_unreadable(value: object) -> bool:
|
|||
return needs_legacy_reader(value) and not legacy_encryption_available()
|
||||
|
||||
|
||||
def decrypt_for_rewrite(value: str, key: str) -> str | None:
|
||||
"""Decrypt a value a config writer submitted for storage: ciphertext read back from the store or a first-write
|
||||
plaintext. Without PyNaCl an unprefixed value cannot be told apart from plaintext, so it is kept as submitted
|
||||
instead of being dropped."""
|
||||
if legacy_unreadable(value):
|
||||
return value
|
||||
return decrypt_value_helper(value=value, key=key, return_original_value=True)
|
||||
|
||||
|
||||
def require_legacy_reader_for(values: Iterable[object], purpose: str) -> None:
|
||||
"""Refuse a decrypt-then-rewrite pass when PyNaCl is missing and one of the values is unprefixed: it would
|
||||
read as unreadable and be dropped, double wrapped or miscounted as plaintext. Versioned gcm and non string
|
||||
|
|
|
|||
|
|
@ -419,6 +419,7 @@ from litellm.proxy.common_utils.debug_utils import init_verbose_loggers
|
|||
from litellm.proxy.common_utils.debug_utils import router as debugging_endpoints_router
|
||||
from litellm.proxy.common_utils.discoverable_model_filter import discoverable_rows, undiscoverable_model_names
|
||||
from litellm.proxy.common_utils.encrypt_decrypt_utils import (
|
||||
decrypt_for_rewrite,
|
||||
decrypt_value_helper,
|
||||
encrypt_value_helper,
|
||||
)
|
||||
|
|
@ -7794,7 +7795,7 @@ class ProxyConfig:
|
|||
_decrypt_and_set_db_env_variables): this is a write path, and
|
||||
loading values into os.environ is the read path's responsibility.
|
||||
"""
|
||||
decrypted_env_vars: Final = self._decrypt_db_variables(environment_variables)
|
||||
decrypted_env_vars: Final = {k: decrypt_for_rewrite(value=v, key=k) for k, v in environment_variables.items()}
|
||||
return self._encrypt_env_variables(
|
||||
environment_variables=decrypted_env_vars,
|
||||
new_encryption_key=new_encryption_key,
|
||||
|
|
|
|||
|
|
@ -3755,11 +3755,13 @@ def test_ProxyConfig__encrypt_env_variables_for_db_without_pynacl_encrypts_new_p
|
|||
monkeypatch.setitem(sys.modules, "nacl.secret", None)
|
||||
pc = ProxyConfig()
|
||||
|
||||
saved = pc._encrypt_env_variables_for_db({"A": v3, "B": "first-write-plaintext"})
|
||||
assert saved["B"].startswith("v3:gcm:") and saved["B"] != "first-write-plaintext"
|
||||
long_plaintext = "A" * 56
|
||||
saved = pc._encrypt_env_variables_for_db({"A": v3, "B": "first-write-plaintext", "C": long_plaintext})
|
||||
assert all(v.startswith("v3:gcm:") for v in saved.values())
|
||||
assert {k: decrypt_value_helper(v, key=k) for k, v in saved.items()} == {
|
||||
"A": "already-migrated",
|
||||
"B": "first-write-plaintext",
|
||||
"C": long_plaintext,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue