chore: initial public snapshot for github upload

This commit is contained in:
Your Name
2026-03-26 20:06:14 +08:00
commit 0e5ecd930e
3497 changed files with 1586236 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
"""
Policy Matcher - Matches requests against policy attachments.
Uses existing wildcard pattern matching helpers to determine which policies
apply to a given request based on team alias, key alias, and model.
Policies are matched via policy_attachments which define WHERE each policy applies.
"""
from typing import Dict, List, Optional
from litellm._logging import verbose_proxy_logger
from litellm.proxy.auth.route_checks import RouteChecks
from litellm.types.proxy.policy_engine import Policy, PolicyMatchContext, PolicyScope
class PolicyMatcher:
"""
Matches incoming requests against policy attachments.
Supports wildcard patterns:
- "*" matches everything
- "prefix-*" matches anything starting with "prefix-"
Uses policy_attachments to determine which policies apply to a request.
"""
@staticmethod
def matches_pattern(value: Optional[str], patterns: List[str]) -> bool:
"""
Check if a value matches any of the given patterns.
Uses the existing RouteChecks._route_matches_wildcard_pattern helper.
Args:
value: The value to check (e.g., team alias, key alias, model)
patterns: List of patterns to match against
Returns:
True if value matches any pattern, False otherwise
"""
# If no value provided, only match if patterns include "*"
if value is None:
return "*" in patterns
for pattern in patterns:
# Use existing wildcard pattern matching helper
if RouteChecks._route_matches_wildcard_pattern(
route=value, pattern=pattern
):
return True
return False
@staticmethod
def scope_matches(scope: PolicyScope, context: PolicyMatchContext) -> bool:
"""
Check if a policy scope matches the given context.
A scope matches if ALL of its fields match:
- teams matches context.team_alias
- keys matches context.key_alias
- models matches context.model
Args:
scope: The policy scope to check
context: The request context
Returns:
True if scope matches context, False otherwise
"""
# Check teams
if not PolicyMatcher.matches_pattern(context.team_alias, scope.get_teams()):
return False
# Check keys
if not PolicyMatcher.matches_pattern(context.key_alias, scope.get_keys()):
return False
# Check models
if not PolicyMatcher.matches_pattern(context.model, scope.get_models()):
return False
# Check tags (only if scope specifies tags)
# Unlike teams/keys/models, empty tags means "do not check" rather than "match all"
scope_tags = scope.get_tags()
if scope_tags:
if not context.tags:
return False
# Match if ANY context tag matches ANY scope tag pattern
if not any(
PolicyMatcher.matches_pattern(tag, scope_tags) for tag in context.tags
):
return False
return True
@staticmethod
def get_matching_policies(
context: PolicyMatchContext,
) -> List[str]:
"""
Get list of policy names that match the given context via attachments.
Args:
context: The request context to match against
Returns:
List of policy names that match the context
"""
from litellm.proxy.policy_engine.attachment_registry import (
get_attachment_registry,
)
registry = get_attachment_registry()
if not registry.is_initialized():
verbose_proxy_logger.debug(
"AttachmentRegistry not initialized, returning empty list"
)
return []
return registry.get_attached_policies(context)
@staticmethod
def get_matching_policies_from_registry(
context: PolicyMatchContext,
) -> List[str]:
"""
Get list of policy names that match the given context from the global registry.
Args:
context: The request context to match against
Returns:
List of policy names that match the context
"""
return PolicyMatcher.get_matching_policies(context=context)
@staticmethod
def get_policies_with_matching_conditions(
policy_names: List[str],
context: PolicyMatchContext,
policies: Optional[Dict[str, Policy]] = None,
) -> List[str]:
"""
Filter policies to only those whose conditions match the context.
A policy's condition matches if:
- The policy has no condition (condition is None), OR
- The policy's condition evaluates to True for the given context
Args:
policy_names: List of policy names to filter
context: The request context to evaluate conditions against
policies: Dictionary of all policies (if None, uses global registry)
Returns:
List of policy names whose conditions match the context
"""
from litellm.proxy.policy_engine.condition_evaluator import ConditionEvaluator
from litellm.proxy.policy_engine.policy_registry import get_policy_registry
if policies is None:
registry = get_policy_registry()
if not registry.is_initialized():
return []
policies = registry.get_all_policies()
matching_policies = []
for policy_name in policy_names:
policy = policies.get(policy_name)
if policy is None:
continue
# Policy matches if it has no condition OR condition evaluates to True
if policy.condition is None or ConditionEvaluator.evaluate(
policy.condition, context
):
matching_policies.append(policy_name)
return matching_policies