mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-16 04:29:31 +00:00
fix(proxy): skip plaintext complexity_router_config in the encryption scanner
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
45d0264cae
commit
47af50f3de
2 changed files with 43 additions and 0 deletions
|
|
@ -476,6 +476,7 @@ _COVERED_TABLE_SPECS: Final = [
|
|||
("sso_identity_assertion", "litellm_ssoidentityassertion", (), ("assertion_b64",)),
|
||||
]
|
||||
_MCP_CREDENTIAL_TABLES: Final = frozenset({"litellm_mcpservertable", "litellm_mcpserveroauthclient"})
|
||||
_PLAINTEXT_LITELLM_PARAMS: Final = frozenset({"complexity_router_config"})
|
||||
|
||||
|
||||
def _iter_encrypted_strings(obj: object):
|
||||
|
|
@ -518,6 +519,8 @@ def _mcp_encrypted_leaves(col: str, raw: object) -> Iterator[str]:
|
|||
def _encrypted_leaves(db_attr: str, col: str, raw: object) -> Iterator[str]:
|
||||
if db_attr in _MCP_CREDENTIAL_TABLES and col in ("credentials", "env_vars"):
|
||||
return _mcp_encrypted_leaves(col, raw)
|
||||
if db_attr == "litellm_proxymodeltable" and isinstance(raw, dict):
|
||||
return _iter_encrypted_strings({k: v for k, v in raw.items() if k not in _PLAINTEXT_LITELLM_PARAMS})
|
||||
return _iter_encrypted_strings(raw)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -159,6 +159,46 @@ async def test_migrate_and_check_refuse_without_pynacl_instead_of_miscounting_le
|
|||
client.db.litellm_config.update.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_check_and_rotation_preflight_pass_without_pynacl_when_only_complexity_router_config_is_plaintext(
|
||||
salt_key, monkeypatch
|
||||
):
|
||||
_enable_aes(monkeypatch)
|
||||
monkeypatch.setitem(sys.modules, "nacl", None)
|
||||
monkeypatch.setitem(sys.modules, "nacl.secret", None)
|
||||
client: Final = MagicMock()
|
||||
_empty_covered_tables(client)
|
||||
client.db.litellm_teamtable.find_many = AsyncMock(return_value=[])
|
||||
client.db.litellm_verificationtoken.find_many = AsyncMock(return_value=[])
|
||||
client.db.litellm_ssoconfig.find_unique = AsyncMock(return_value=None)
|
||||
client.db.litellm_config.find_unique = AsyncMock(return_value=None)
|
||||
client.db.litellm_proxymodeltable.find_many = AsyncMock(
|
||||
return_value=[
|
||||
SimpleNamespace(
|
||||
litellm_params={
|
||||
"api_key": encrypt_value_helper("migrated-secret"),
|
||||
"complexity_router_config": {
|
||||
"strong_model": "gpt-5.1",
|
||||
"opensource_classifier_config": {"api_base": "http://classifier.internal"},
|
||||
},
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
report: Final = await cm.check_encryption(prisma_client=client)
|
||||
|
||||
assert report.residual_legacy == 0, report.to_dict()
|
||||
assert report.as_dict()["locations"]["model_table"] == {
|
||||
"scanned": 1,
|
||||
"migrated": 0,
|
||||
"already_v2": 1,
|
||||
"plaintext": 0,
|
||||
"undecryptable": 0,
|
||||
"legacy": 0,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"db_attr, build_row",
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue