fix(proxy): make /config/update env-var encryption idempotent - #28022
Conversation
A single decrypt-then-encrypt chokepoint (_encrypt_env_variables_for_db) now backs both update_config and save_config. Re-submitting a value the Admin UI read back from /get/config/callbacks as ciphertext no longer stacks a second encryption layer, which previously decrypted to garbage and silently broke the callback. The chokepoint decrypts with the pure _decrypt_db_variables (no os.environ mutation on the write path) and encrypts exactly once; update_config merges only the sent keys so untouched env vars keep their stored ciphertext byte-for-byte.
Greptile SummaryFixes double-encryption of
Confidence Score: 4/5Safe to merge; the fix is narrowly scoped to the env-var encryption write path and does not touch auth, routing, or any other critical proxy logic. The decrypt-then-encrypt pattern is correct: No files require special attention; both changed files are self-contained and the new test covers the key edge cases.
|
| Filename | Overview |
|---|---|
| litellm/proxy/proxy_server.py | Introduces _encrypt_env_variables_for_db (decrypt-then-encrypt chokepoint) and routes both save_config and update_config through it, eliminating the double-encryption stacking bug; logic is sound and backward-compatible. |
| tests/test_litellm/proxy/test_proxy_server.py | Adds test_encrypt_env_variables_for_db_is_idempotent — a pure mock test that verifies plaintext→ciphertext, ciphertext re-feed ×3, and no os.environ mutation; no real network calls, matches existing test-file conventions. |
Reviews (1): Last reviewed commit: "fix(proxy): make /config/update env-var ..." | Re-trigger Greptile
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…encryption Adds test_update_config_env_var_round_trip_not_double_encrypted, which drives the real /config/update handler: first write plaintext, then re-POST the stored ciphertext (the Admin UI round-trip) and assert the value is not stacked with a second encryption layer and untouched keys stay byte-identical. Verified to fail against the pre-fix handler and pass after. Also tightens the unit test to exactly three ciphertext re-feeds.
…tani-e592b4 fix(proxy): make /config/update env-var encryption idempotent
Summary
POST /config/updatere-encryptedenvironment_variableson every save with no decrypt-first guard. When the Admin UI read config back via/get/config/callbacks(which returns the stored, still-encrypted value) and re-POSTed it on the next save, the handler stacked a second encryption layer. The doubly-encrypted value decrypted to ciphertext at load time, was pushed intoos.environas the API key, and silently broke the callback.save_configwas already idempotent (decrypt-then-encrypt);update_confighad dropped that guard — the env-var write logic was duplicated and the two copies diverged.ProxyConfig._encrypt_env_variables_for_db, and routes bothupdate_configandsave_configthrough it. It decrypts via the pure_decrypt_db_variables(noos.environmutation on the write path) then encrypts exactly once.update_configmerges only the sent keys, so untouched env vars keep their stored ciphertext byte-for-byte.Test plan
test_encrypt_env_variables_for_db_is_idempotent— plaintext → ciphertext, then ciphertext fed back in ×3, asserts the stored value always decrypts to the original plaintext in exactly one layer, and thatos.environis not mutated on the write path.pytest tests/test_litellm/proxy/test_proxy_server.py -k "encrypt_env_variables_for_db or update_config or env_var or environment"— 14 passed.pytest tests/test_litellm/proxy/management_endpoints/test_config_override_endpoints.py test_delete_callbacks_endpoint.py— 6 passed.POST /config/updatenow decrypts back to plaintext (failed before the change, passes after); first-write, plaintext re-save, and cross-section update adjacency all pass before and after.Note
Medium Risk
Touches environment-variable encryption on config write paths; a mistake could corrupt stored secrets or break integrations relying on decrypted values.
Overview
Fixes a double-encryption bug when updating
environment_variablesviaPOST /config/updateby routing writes through a new idempotent helper,ProxyConfig._encrypt_env_variables_for_db, which decrypts-then-encrypts once and avoids mutatingos.environon the write path.Updates
save_configto use the same helper and adjusts/config/updatemerging so only provided keys are re-written while untouched env vars remain byte-identical in the DB. Adds unit and endpoint-level regression tests to ensure repeated ciphertext round-trips never stack encryption layers.Reviewed by Cursor Bugbot for commit a4a1726. Bugbot is set up for automated code reviews on this repo. Configure here.