mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
fix(mcp): hash connection credentials in auth failure metadata
This commit is contained in:
parent
23ea0ee428
commit
2c9faf2c40
3 changed files with 13 additions and 10 deletions
|
|
@ -3300,7 +3300,7 @@ class UserAPIKeyAuth(LiteLLM_VerificationTokenView): # the expected response ob
|
|||
normalized = api_key
|
||||
if normalized[:7].lower() == "bearer ":
|
||||
normalized = normalized[7:]
|
||||
if normalized.startswith("sk-"):
|
||||
if normalized.startswith(("sk-", "llm_caccess_", "llm_crefresh_")):
|
||||
return hash_token(normalized)
|
||||
from litellm.proxy.auth.handle_jwt import JWTHandler
|
||||
|
||||
|
|
|
|||
|
|
@ -594,9 +594,10 @@ async def test_resolved_identity_exported_on_auth_failure():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_auth_failure_without_resolved_identity_still_logs():
|
||||
@pytest.mark.parametrize("api_key", ["sk-unknown", "llm_caccess_sealed-test-access", "llm_crefresh_sealed-test-refresh"])
|
||||
async def test_auth_failure_without_resolved_identity_still_logs(api_key):
|
||||
"""When auth fails before any identity is resolved (e.g. an unknown key),
|
||||
the handler must still log a usable object carrying the raw api key and
|
||||
the handler must still log a usable object carrying the hashed api key and
|
||||
route, not crash on the missing identity."""
|
||||
handler = UserAPIKeyAuthExceptionHandler()
|
||||
|
||||
|
|
@ -625,14 +626,14 @@ async def test_auth_failure_without_resolved_identity_still_logs():
|
|||
{},
|
||||
"/v1/chat/completions",
|
||||
None,
|
||||
"sk-unknown",
|
||||
api_key,
|
||||
)
|
||||
|
||||
logged = mock_hook.call_args[1]["user_api_key_dict"]
|
||||
# Raw key must NOT land on the object — it would be promoted into telemetry
|
||||
# as litellm.api_key.hash and leak a real sk-... to anyone reading the trace.
|
||||
assert logged.api_key != "sk-unknown"
|
||||
assert logged.api_key == UserAPIKeyAuth(api_key="sk-unknown").api_key
|
||||
assert logged.api_key != api_key
|
||||
assert logged.api_key == UserAPIKeyAuth(api_key=api_key).api_key
|
||||
assert logged.request_route == "/v1/chat/completions"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ def test_the_server_sets_a_marker_by_assignment_after_construction(marker):
|
|||
assert getattr(auth, marker) == "set-by-the-server"
|
||||
|
||||
|
||||
def test_a_virtual_key_is_hashed_out_of_the_auth_object():
|
||||
raw_key = "sk-1234567890abcdefghij"
|
||||
@pytest.mark.parametrize("prefix", ["sk-", "llm_caccess_", "llm_crefresh_"])
|
||||
def test_a_virtual_key_is_hashed_out_of_the_auth_object(prefix):
|
||||
raw_key = prefix + "1234567890abcdefghij"
|
||||
|
||||
auth = UserAPIKeyAuth(api_key=raw_key)
|
||||
|
||||
|
|
@ -57,8 +58,9 @@ def test_a_virtual_key_is_hashed_out_of_the_auth_object():
|
|||
assert auth.token == auth.api_key
|
||||
|
||||
|
||||
def test_a_bearer_prefixed_key_hashes_the_same_as_the_bare_key():
|
||||
raw_key = "sk-1234567890abcdefghij"
|
||||
@pytest.mark.parametrize("prefix", ["sk-", "llm_caccess_", "llm_crefresh_"])
|
||||
def test_a_bearer_prefixed_key_hashes_the_same_as_the_bare_key(prefix):
|
||||
raw_key = prefix + "1234567890abcdefghij"
|
||||
|
||||
assert UserAPIKeyAuth(api_key=f"Bearer {raw_key}").token == UserAPIKeyAuth(api_key=raw_key).token
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue