Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b8e367d
πŸ› fix(proxy_server): remove redundant decryption of already-decrypted…
danielaskdd Mar 25, 2026
9ef938a
βœ… test(proxy_unit_tests): update decrypt_value_helper mock in callbac…
danielaskdd Mar 25, 2026
b8adffc
✨ feat(proxy): decrypt env vars in get_config for both DB and YAML modes
danielaskdd Mar 26, 2026
687b1c1
πŸ› fix(health_endpoints): resolve TEST_EMAIL_ADDRESS not read from DB …
danielaskdd Mar 26, 2026
631942d
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 1, 2026
aa19b74
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 1, 2026
8d4b8ce
✨ feat(health): add database-backed test email resolution for email h…
danielaskdd Apr 1, 2026
277e398
♻️ refactor(health_endpoints): eliminate proxy startup import cycles
danielaskdd Apr 1, 2026
e2a3ccc
♻️ refactor(health_endpoints): eliminate proxy import cycles in healt…
danielaskdd Apr 1, 2026
d341828
♻️ refactor(health_endpoints): extract encryption utilities and updat…
danielaskdd Apr 1, 2026
c87f7c8
♻️ refactor(encrypt_decrypt): extract signing key logic to dedicated …
danielaskdd Apr 1, 2026
659c6aa
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 1, 2026
38d9e4c
βœ… test(health_endpoints): add comprehensive unit tests for helper fun…
danielaskdd Apr 2, 2026
870a789
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 3, 2026
a8b853d
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 5, 2026
33bf45d
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 9, 2026
0f7c9f4
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 9, 2026
5e9ca6d
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 10, 2026
3cf35a6
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 10, 2026
ff5c330
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 10, 2026
29fb312
Merge branch 'main' into fix/redundant-decrption
danielaskdd Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions litellm/proxy/proxy_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12624,11 +12624,7 @@ def normalize_callback(callback):
_value = os.getenv("SLACK_WEBHOOK_URL", None)
_slack_env_vars[_var] = _value
else:
# decode + decrypt the value
_decrypted_value = decrypt_value_helper(
value=env_variable, key=_var
)
_slack_env_vars[_var] = _decrypted_value
_slack_env_vars[_var] = env_variable

_alerting_types = proxy_logging_obj.slack_alerting_instance.alert_types
_all_alert_types = (
Expand Down Expand Up @@ -12662,9 +12658,7 @@ def normalize_callback(callback):
if env_variable is None:
_email_env_vars[_var] = None
else:
# decode + decrypt the value
_decrypted_value = decrypt_value_helper(value=env_variable, key=_var)
_email_env_vars[_var] = _decrypted_value
_email_env_vars[_var] = env_variable

alerting_data.append(
{
Expand Down
58 changes: 58 additions & 0 deletions tests/proxy_unit_tests/test_proxy_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2720,6 +2720,64 @@ async def test_get_config_callbacks_environment_variables(client_no_auth):
assert otel_vars["OTEL_HEADERS"] == "key=value"


@pytest.mark.asyncio
async def test_get_config_callbacks_email_and_slack_values_are_not_decrypted_again(
client_no_auth,
):
"""
Test that /get/config/callbacks returns already-decrypted email/slack values as-is.
"""
mock_config_data = {
"litellm_settings": {},
"environment_variables": {
"SLACK_WEBHOOK_URL": "https://hooks.slack.com/services/test/webhook",
"SMTP_HOST": "10.16.68.20",
"SMTP_PORT": "587",
"SMTP_USERNAME": "smtp-user",
"SMTP_PASSWORD": "smtp-password",
"SMTP_SENDER_EMAIL": "alerts@example.com",
"TEST_EMAIL_ADDRESS": "ops@example.com",
"EMAIL_LOGO_URL": "https://example.com/logo.png",
"EMAIL_SUPPORT_CONTACT": "support@example.com",
},
"general_settings": {"alerting": ["slack"]},
}

proxy_config = getattr(litellm.proxy.proxy_server, "proxy_config")

with patch.object(
proxy_config, "get_config", new=AsyncMock(return_value=mock_config_data)
), patch(
"litellm.proxy.proxy_server.decrypt_value_helper",
side_effect=AssertionError("decrypt_value_helper should not be called"),
) as decrypt_mock:
response = client_no_auth.get("/get/config/callbacks")

assert response.status_code == 200
result = response.json()
alerts = result["alerts"]

slack_alert = next((alert for alert in alerts if alert["name"] == "slack"), None)
assert slack_alert is not None
assert slack_alert["variables"] == {
"SLACK_WEBHOOK_URL": "https://hooks.slack.com/services/test/webhook"
}

email_alert = next((alert for alert in alerts if alert["name"] == "email"), None)
assert email_alert is not None
assert email_alert["variables"] == {
"SMTP_HOST": "10.16.68.20",
"SMTP_PORT": "587",
"SMTP_USERNAME": "smtp-user",
"SMTP_PASSWORD": "smtp-password",
"SMTP_SENDER_EMAIL": "alerts@example.com",
"TEST_EMAIL_ADDRESS": "ops@example.com",
"EMAIL_LOGO_URL": "https://example.com/logo.png",
"EMAIL_SUPPORT_CONTACT": "support@example.com",
}
decrypt_mock.assert_not_called()


@pytest.mark.asyncio
async def test_update_config_success_callback_normalization():
"""
Expand Down
Loading