add test(tag-routing): prevent header regex bypass for strict plain tags.

Add tests to validate the condition

 improve the conditional readability by naming the plain-tag check explicitly.
This commit is contained in:
harish-berri 2026-04-29 20:14:30 +00:00
parent 8dda834cf9
commit 25cf097da8
2 changed files with 30 additions and 1 deletions

View file

@ -106,7 +106,8 @@ def _match_deployment(
# check either didn't run (no request tags) or failed (step 1 returned
# None). Block the regex path so it cannot circumvent the operator's
# strict-tag policy.
strict_tag_check_failed = not match_any and bool(deployment_tags)
deployment_has_plain_tags = deployment_tags is not None and len(deployment_tags) > 0
strict_tag_check_failed = not match_any and deployment_has_plain_tags
if deployment_tag_regex and header_strings and not strict_tag_check_failed:
regex_match = _is_valid_deployment_tag_regex(
deployment_tag_regex, header_strings

View file

@ -346,6 +346,34 @@ def test_tag_routing_with_list_of_tags_match_all():
assert not is_valid_deployment_tag(["default"], ["teamA"], match_any=False)
def test_strict_tag_routing_without_request_tags_blocks_header_regex_fallback():
"""
When tag_filtering_match_any=False, deployments with plain tags must require
those request tags before header regex can match. A spoofed User-Agent must
not route to a tagged deployment when the request has no tags.
"""
from litellm.router_strategy.tag_based_routing import _match_deployment
deployment = {
"model_name": "restricted-model",
"litellm_params": {
"model": "gpt-4o",
"tags": ["internal"],
"tag_regex": ["^User-Agent: internal-tool"],
},
}
assert (
_match_deployment(
deployment=deployment,
request_tags=None,
header_strings=["User-Agent: internal-tool"],
match_any=False,
)
is None
)
@pytest.mark.asyncio()
async def test_router_free_paid_tier_with_responses_api():
"""