mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix: address greptile feedback
This commit is contained in:
parent
9864e28dbd
commit
e75824dab3
4 changed files with 161 additions and 113 deletions
|
|
@ -215,7 +215,55 @@
|
|||
"financial-pii"
|
||||
],
|
||||
"complexity": "Low",
|
||||
"guardrailDefinitions": [],
|
||||
"guardrailDefinitions": [
|
||||
{
|
||||
"guardrail_name": "au-pii-tax-identifiers",
|
||||
"litellm_params": {
|
||||
"guardrail": "litellm_content_filter",
|
||||
"mode": "pre_call",
|
||||
"patterns": [
|
||||
{"pattern_type": "prebuilt", "pattern_name": "au_tfn", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "au_abn", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "au_medicare", "action": "MASK"}
|
||||
],
|
||||
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
|
||||
},
|
||||
"guardrail_info": {"description": "Masks Australian Tax File Numbers, Business Numbers, and Medicare Numbers"}
|
||||
},
|
||||
{
|
||||
"guardrail_name": "credentials-api-keys",
|
||||
"litellm_params": {
|
||||
"guardrail": "litellm_content_filter",
|
||||
"mode": "pre_call",
|
||||
"patterns": [
|
||||
{"pattern_type": "prebuilt", "pattern_name": "aws_access_key", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "aws_secret_key", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "github_token", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "slack_token", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "generic_api_key", "action": "BLOCK"}
|
||||
],
|
||||
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
|
||||
},
|
||||
"guardrail_info": {"description": "Blocks requests containing API keys and credentials (AWS, GitHub, Slack)"}
|
||||
},
|
||||
{
|
||||
"guardrail_name": "financial-pii",
|
||||
"litellm_params": {
|
||||
"guardrail": "litellm_content_filter",
|
||||
"mode": "pre_call",
|
||||
"patterns": [
|
||||
{"pattern_type": "prebuilt", "pattern_name": "visa", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "mastercard", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "amex", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "discover", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "credit_card", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "iban", "action": "MASK"}
|
||||
],
|
||||
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
|
||||
},
|
||||
"guardrail_info": {"description": "Masks financial information including credit cards and bank account numbers"}
|
||||
}
|
||||
],
|
||||
"templateData": {
|
||||
"policy_name": "baseline-pii-protection",
|
||||
"description": "Baseline PII protection for internal tools and testing. Focuses on credentials and high-risk identifiers only.",
|
||||
|
|
|
|||
|
|
@ -370,38 +370,40 @@
|
|||
},
|
||||
{
|
||||
"name": "au_tfn",
|
||||
"display_name": "TFN - Australian Tax File Number",
|
||||
"display_name": "TFN (Australian Tax File Number)",
|
||||
"pattern": "\\b\\d{8,9}\\b",
|
||||
"category": "Australian PII Patterns",
|
||||
"description": "Detects Australian Tax File Numbers (8 or 9 digits)"
|
||||
"category": "PII Patterns",
|
||||
"description": "Detects Australian Tax File Numbers (8-9 digits) only when near TFN/tax file context to avoid false positives on arbitrary numbers",
|
||||
"keyword_pattern": "\\b(?:TFN|T\\.F\\.N\\.|tax\\s*file\\s*(?:number|no\\.?)|tax\\s*file\\s*#?|ATO\\s*number)\\b",
|
||||
"allow_word_numbers": false
|
||||
},
|
||||
{
|
||||
"name": "au_abn",
|
||||
"display_name": "ABN - Australian Business Number",
|
||||
"display_name": "ABN (Australian Business Number)",
|
||||
"pattern": "\\b\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{3}\\b",
|
||||
"category": "Australian PII Patterns",
|
||||
"description": "Detects Australian Business Numbers (11 digits, optionally space-separated)"
|
||||
"category": "PII Patterns",
|
||||
"description": "Detects Australian Business Numbers (11 digits, optional spaces: XX XXX XXX XXX)"
|
||||
},
|
||||
{
|
||||
"name": "au_medicare",
|
||||
"display_name": "Australian Medicare Number",
|
||||
"pattern": "\\b\\d{4}\\s?\\d{5}\\s?\\d(?:\\s?\\d)?\\b",
|
||||
"category": "Australian PII Patterns",
|
||||
"description": "Detects Australian Medicare numbers (10 digits + optional reference digit)"
|
||||
"display_name": "Medicare Number (Australia)",
|
||||
"pattern": "\\b(?:\\d{4}\\s?\\d{5}\\s?\\d{1}|\\d{11})\\b",
|
||||
"category": "PII Patterns",
|
||||
"description": "Detects Australian Medicare numbers (formatted XXXX XXXXX X or 11 consecutive digits)"
|
||||
},
|
||||
{
|
||||
"name": "iban",
|
||||
"display_name": "IBAN - International Bank Account Number",
|
||||
"display_name": "IBAN (International Bank Account Number)",
|
||||
"pattern": "\\b[A-Z]{2}\\d{2}[A-Z0-9]{11,30}\\b",
|
||||
"category": "Banking Patterns",
|
||||
"description": "Detects International Bank Account Numbers (IBAN format: 2 country letters, 2 check digits, 11-30 alphanumeric)"
|
||||
"category": "Payment Card Patterns",
|
||||
"description": "Detects IBANs (2 letter country code + 2 check digits + 4 char bank code + 7 digit base + optional 0-16 alphanumeric)"
|
||||
},
|
||||
{
|
||||
"name": "street_address",
|
||||
"display_name": "Street Address (AU/US/UK)",
|
||||
"pattern": "(?i)\\b\\d{1,5}(?:[-\\s]?\\d+)?\\s+[A-Z][a-z]*(?:\\s+[A-Z][a-z]*)*\\s+(?:Street|St\\.?|Road|Rd\\.?|Avenue|Ave\\.?|Drive|Dr\\.?|Court|Ct\\.?|Lane|Ln\\.?|Terrace|Tce\\.?|Way|Boulevard|Blvd\\.?)\\b(?:,?\\s*(?:[A-Z][a-z]*(?:\\s+[A-Z][a-z]*)*))*?(?:,?\\s*[A-Z]{2,3}\\s*\\d{4})?(?:,?\\s*[A-Z][a-z]*(?:\\s+[A-Z][a-z]*)*)?(?:,?\\s*Australia|USA|United States|UK)?",
|
||||
"display_name": "Street Address",
|
||||
"pattern": "\\b\\d{1,6}\\s+[A-Za-z0-9][A-Za-z0-9\\s.'-]*\\s+(?:Street|St|Avenue|Ave|Road|Rd|Boulevard|Blvd|Drive|Dr|Lane|Ln|Way|Court|Ct|Place|Pl|Circle|Cir)\\b",
|
||||
"category": "PII Patterns",
|
||||
"description": "Detects street addresses in Australian, US, and UK formats"
|
||||
"description": "Detects street addresses (number + street name + street type)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -6,15 +6,12 @@ All /policy management endpoints
|
|||
/policy/validate - Validate a policy configuration
|
||||
/policy/list - List all loaded policies
|
||||
/policy/info - Get information about a specific policy
|
||||
/policy/templates - Get available policy templates
|
||||
/policy/templates - Get policy templates (GitHub with local fallback)
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
from importlib.resources import files
|
||||
from typing import Any, List
|
||||
|
||||
import httpx
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
|
||||
from litellm._logging import verbose_proxy_logger
|
||||
|
|
@ -36,82 +33,6 @@ from litellm.types.proxy.policy_engine import (
|
|||
router = APIRouter()
|
||||
|
||||
|
||||
# Policy Templates GitHub URL
|
||||
POLICY_TEMPLATES_GITHUB_URL = (
|
||||
"https://raw.githubusercontent.com/BerriAI/litellm/main/policy_templates.json"
|
||||
)
|
||||
|
||||
|
||||
def load_local_policy_templates() -> List[Any]:
|
||||
"""Load the local backup policy templates bundled with the package."""
|
||||
try:
|
||||
content = json.loads(
|
||||
files("litellm")
|
||||
.joinpath("policy_templates_backup.json")
|
||||
.read_text(encoding="utf-8")
|
||||
)
|
||||
return content
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.error(f"Failed to load local policy templates backup: {e}")
|
||||
return []
|
||||
|
||||
|
||||
def fetch_remote_policy_templates(url: str, timeout: int = 5) -> List[Any]:
|
||||
"""
|
||||
Fetch policy templates from a remote URL.
|
||||
|
||||
Returns the parsed JSON list. Falls back to local backup on any error.
|
||||
"""
|
||||
try:
|
||||
response = httpx.get(url, timeout=timeout)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.warning(
|
||||
f"Failed to fetch policy templates from {url}: {e}. "
|
||||
"Falling back to local backup."
|
||||
)
|
||||
return load_local_policy_templates()
|
||||
|
||||
|
||||
def get_policy_templates_list() -> List[Any]:
|
||||
"""
|
||||
Get policy templates with GitHub fallback to local backup.
|
||||
|
||||
1. Try to fetch from GitHub URL (https://raw.githubusercontent.com/BerriAI/litellm/main/policy_templates.json)
|
||||
2. On any failure, fall back to local backup (litellm/policy_templates_backup.json)
|
||||
3. Validate that result is a non-empty list
|
||||
|
||||
Set LITELLM_LOCAL_POLICY_TEMPLATES=true to always use local backup.
|
||||
"""
|
||||
# Check if we should use local only (LITELLM_LOCAL_POLICY_TEMPLATES=true)
|
||||
use_local_only = os.getenv("LITELLM_LOCAL_POLICY_TEMPLATES", "").lower() == "true"
|
||||
|
||||
if use_local_only:
|
||||
verbose_proxy_logger.info(
|
||||
"Using local policy templates (LITELLM_LOCAL_POLICY_TEMPLATES=true)"
|
||||
)
|
||||
return load_local_policy_templates()
|
||||
|
||||
# Fetch from GitHub (automatically falls back to local on any error)
|
||||
templates = fetch_remote_policy_templates(POLICY_TEMPLATES_GITHUB_URL)
|
||||
|
||||
# Validate it's a non-empty list
|
||||
if not isinstance(templates, list):
|
||||
verbose_proxy_logger.warning(
|
||||
f"Policy templates is not a list (type={type(templates).__name__}). "
|
||||
"Using local backup."
|
||||
)
|
||||
return load_local_policy_templates()
|
||||
|
||||
if len(templates) == 0:
|
||||
verbose_proxy_logger.warning("Policy templates is empty. Using local backup.")
|
||||
return load_local_policy_templates()
|
||||
|
||||
verbose_proxy_logger.debug(f"Successfully loaded {len(templates)} policy templates")
|
||||
return templates
|
||||
|
||||
|
||||
@router.post(
|
||||
"/policy/validate",
|
||||
tags=["policy management"],
|
||||
|
|
@ -342,6 +263,24 @@ async def test_policy_matching(
|
|||
)
|
||||
|
||||
|
||||
POLICY_TEMPLATES_GITHUB_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/policy_templates.json"
|
||||
|
||||
|
||||
def _load_policy_templates_from_local_backup() -> list:
|
||||
"""Load policy templates from local backup file (litellm/policy_templates_backup.json)."""
|
||||
backup_path = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"..",
|
||||
"..",
|
||||
"policy_templates_backup.json",
|
||||
)
|
||||
path = os.path.abspath(backup_path)
|
||||
if not os.path.exists(path):
|
||||
return []
|
||||
with open(path, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/policy/templates",
|
||||
tags=["policy management"],
|
||||
|
|
@ -351,24 +290,35 @@ async def test_policy_matching(
|
|||
async def get_policy_templates(
|
||||
request: Request,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
) -> List[Any]:
|
||||
) -> list:
|
||||
"""
|
||||
Get available policy templates for quick policy setup.
|
||||
Get policy templates for the UI (pre-configured guardrail combinations).
|
||||
|
||||
Returns a list of pre-configured policy templates that users can use
|
||||
as a starting point for creating their own policies.
|
||||
|
||||
Templates are fetched from GitHub by default, with fallback to local backup.
|
||||
Set LITELLM_LOCAL_POLICY_TEMPLATES=true to always use local backup.
|
||||
Fetches from GitHub with automatic fallback to local backup on failure.
|
||||
Set LITELLM_LOCAL_POLICY_TEMPLATES=true to skip GitHub and use local backup only.
|
||||
"""
|
||||
use_local = os.getenv("LITELLM_LOCAL_POLICY_TEMPLATES", "").strip().lower() in (
|
||||
"true",
|
||||
"1",
|
||||
"yes",
|
||||
)
|
||||
if use_local:
|
||||
return _load_policy_templates_from_local_backup()
|
||||
|
||||
try:
|
||||
templates = get_policy_templates_list()
|
||||
verbose_proxy_logger.debug(f"Loaded {len(templates)} policy templates")
|
||||
return templates
|
||||
from litellm.llms.custom_httpx.http_handler import get_async_httpx_client
|
||||
from litellm.types.llms.custom_http import httpxSpecialProvider
|
||||
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.error(f"Error loading policy templates: {e}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Error loading policy templates: {str(e)}",
|
||||
async_client = get_async_httpx_client(
|
||||
llm_provider=httpxSpecialProvider.UI,
|
||||
params={"timeout": 10.0},
|
||||
)
|
||||
response = await async_client.get(POLICY_TEMPLATES_GITHUB_URL)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
verbose_proxy_logger.debug(
|
||||
"Failed to fetch policy templates from GitHub, using local backup: %s", e
|
||||
)
|
||||
|
||||
return _load_policy_templates_from_local_backup()
|
||||
|
|
|
|||
|
|
@ -215,7 +215,55 @@
|
|||
"financial-pii"
|
||||
],
|
||||
"complexity": "Low",
|
||||
"guardrailDefinitions": [],
|
||||
"guardrailDefinitions": [
|
||||
{
|
||||
"guardrail_name": "au-pii-tax-identifiers",
|
||||
"litellm_params": {
|
||||
"guardrail": "litellm_content_filter",
|
||||
"mode": "pre_call",
|
||||
"patterns": [
|
||||
{"pattern_type": "prebuilt", "pattern_name": "au_tfn", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "au_abn", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "au_medicare", "action": "MASK"}
|
||||
],
|
||||
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
|
||||
},
|
||||
"guardrail_info": {"description": "Masks Australian Tax File Numbers, Business Numbers, and Medicare Numbers"}
|
||||
},
|
||||
{
|
||||
"guardrail_name": "credentials-api-keys",
|
||||
"litellm_params": {
|
||||
"guardrail": "litellm_content_filter",
|
||||
"mode": "pre_call",
|
||||
"patterns": [
|
||||
{"pattern_type": "prebuilt", "pattern_name": "aws_access_key", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "aws_secret_key", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "github_token", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "slack_token", "action": "BLOCK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "generic_api_key", "action": "BLOCK"}
|
||||
],
|
||||
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
|
||||
},
|
||||
"guardrail_info": {"description": "Blocks requests containing API keys and credentials (AWS, GitHub, Slack)"}
|
||||
},
|
||||
{
|
||||
"guardrail_name": "financial-pii",
|
||||
"litellm_params": {
|
||||
"guardrail": "litellm_content_filter",
|
||||
"mode": "pre_call",
|
||||
"patterns": [
|
||||
{"pattern_type": "prebuilt", "pattern_name": "visa", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "mastercard", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "amex", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "discover", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "credit_card", "action": "MASK"},
|
||||
{"pattern_type": "prebuilt", "pattern_name": "iban", "action": "MASK"}
|
||||
],
|
||||
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
|
||||
},
|
||||
"guardrail_info": {"description": "Masks financial information including credit cards and bank account numbers"}
|
||||
}
|
||||
],
|
||||
"templateData": {
|
||||
"policy_name": "baseline-pii-protection",
|
||||
"description": "Baseline PII protection for internal tools and testing. Focuses on credentials and high-risk identifiers only.",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue