fix(anthropic): resolve the WIF identity source from a dense litellm_params dump

This commit is contained in:
mateo-berri 2026-08-29 14:40:21 -07:00
parent a7ed6003f6
commit 230b7f6bea
2 changed files with 21 additions and 1 deletions

View file

@ -141,7 +141,9 @@ def _resolve_identity_source(
if source_kind is None:
legacy_ref: Final = _resolve_assertion_ref(litellm_params)
return (legacy_ref, None) if legacy_ref is not None else None
params: Final = litellm_params if litellm_params is not None else _EMPTY_PARAMS
params: Final[Mapping[str, object]] = MappingProxyType(
{key: value for key, value in (litellm_params or _EMPTY_PARAMS).items() if value is not None}
)
match source_kind:
case AnthropicIdentitySourceKind.internal_issuer.value:
_reject_foreign_variant_fields(params, foreign_field_map=_KEYCLOAK_FIELD_MAP, chosen_kind=source_kind)

View file

@ -25,6 +25,7 @@ from litellm.llms.base_llm.auth.identity_source import (
)
from litellm.llms.base_llm.auth.jwt_signing import build_jwks, rfc7638_thumbprint
from litellm.llms.base_llm.auth.token_exchange import JwtBearerTokenExchangeEngine
from litellm.types.router import GenericLiteLLMParams
from litellm.llms.base_llm.auth.types import (
AssertionSourceError,
ExchangeError,
@ -930,6 +931,23 @@ class TestKeycloakIdentitySourceDispatch:
assert first.assertion_ref != second.assertion_ref
@pytest.mark.parametrize(
"sparse_params",
[TestInternalIssuerIdentitySourceDispatch.LITELLM_PARAMS, TestKeycloakIdentitySourceDispatch.LITELLM_PARAMS],
ids=["internal_issuer", "keycloak"],
)
def test_dense_router_params_dump_resolves_like_the_sparse_config(sparse_params: Mapping[str, object]):
dense_params = dict(GenericLiteLLMParams(**sparse_params))
assert any(value is None for value in dense_params.values())
dense = resolve_anthropic_wif_params(dense_params)
sparse = resolve_anthropic_wif_params(sparse_params)
assert dense is not None and sparse is not None
assert dense.assertion_ref == sparse.assertion_ref
class TestIdentitySourceValidationFailsClosed:
"""Unknown discriminator, a missing required variant field, and a field belonging to the
other variant are all hard config errors at resolution time -- never a silent fallback to