feat: policy_templates.json

support hosted policy templates

allows others to contribute to the policy templates
This commit is contained in:
Krrish Dholakia 2026-02-11 21:24:40 -08:00
parent 4341b8a5b9
commit 3db36ed4a4
7 changed files with 356 additions and 414 deletions

View file

@ -765,6 +765,7 @@ router_settings:
| LITELLM_KEY_ROTATION_CHECK_INTERVAL_SECONDS | Interval in seconds for how often to run job that auto-rotates keys. Default is 86400 (24 hours).
| LITELLM_LICENSE | License key for LiteLLM usage
| LITELLM_LOCAL_MODEL_COST_MAP | Local configuration for model cost mapping in LiteLLM
| LITELLM_LOCAL_POLICY_TEMPLATES | When set to "true", uses local backup policy templates instead of fetching from GitHub. Policy templates are fetched from https://raw.githubusercontent.com/BerriAI/litellm/main/policy_templates.json by default, with automatic fallback to local backup on failure
| LITELLM_LOG | Enable detailed logging for LiteLLM
| LITELLM_MODEL_COST_MAP_URL | URL for fetching model cost map data. Default is https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json
| LITELLM_LOG_FILE | File path to write LiteLLM logs to. When set, logs will be written to both console and the specified file

View file

@ -13,389 +13,3 @@ model_list:
- model_name: gpt-4.1-mini
litellm_params:
model: openai/gpt-4.1-mini
# ==============================================================================
# GUARDRAILS - PII Detection for Fortescue (Australian Mining Company)
# ==============================================================================
guardrails:
# --------------------------------------------------------------------------
# 1. AUSTRALIAN-SPECIFIC PII PATTERNS
# --------------------------------------------------------------------------
- guardrail_name: au-pii-tax-identifiers
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# Australian Tax File Number (8-9 digits)
- pattern_type: prebuilt
pattern_name: au_tfn
action: MASK
# Australian Business Number (11 digits)
- pattern_type: prebuilt
pattern_name: au_abn
action: MASK
# Australian Medicare Number
- pattern_type: prebuilt
pattern_name: au_medicare
action: MASK
pattern_redaction_format: "[{pattern_name}_REDACTED]"
- guardrail_name: au-pii-passports
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# Australian passport (critical for mining contractors/fly-in-fly-out workers)
- pattern_type: prebuilt
pattern_name: passport_australia
action: MASK
pattern_redaction_format: "[PASSPORT_REDACTED]"
# --------------------------------------------------------------------------
# 2. INTERNATIONAL PII (for global workforce)
# --------------------------------------------------------------------------
- guardrail_name: international-pii-identifiers
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# US employees/contractors
- pattern_type: prebuilt
pattern_name: us_ssn
action: MASK
- pattern_type: prebuilt
pattern_name: us_ssn_no_dash
action: MASK
- pattern_type: prebuilt
pattern_name: passport_us
action: MASK
# UK operations
- pattern_type: prebuilt
pattern_name: passport_uk
action: MASK
# European operations
- pattern_type: prebuilt
pattern_name: passport_germany
action: MASK
- pattern_type: prebuilt
pattern_name: passport_france
action: MASK
- pattern_type: prebuilt
pattern_name: passport_netherlands
action: MASK
# Dutch BSN (contextual)
- pattern_type: prebuilt
pattern_name: nl_bsn_contextual
action: MASK
# Asian Pacific operations
- pattern_type: prebuilt
pattern_name: passport_china
action: MASK
- pattern_type: prebuilt
pattern_name: passport_india
action: MASK
- pattern_type: prebuilt
pattern_name: passport_japan
action: MASK
# Canadian operations
- pattern_type: prebuilt
pattern_name: passport_canada
action: MASK
# South American operations (mining companies often have Brazilian presence)
- pattern_type: prebuilt
pattern_name: br_cpf
action: MASK
- pattern_type: prebuilt
pattern_name: br_cpf_unformatted
action: MASK
- pattern_type: prebuilt
pattern_name: br_rg
action: MASK
- pattern_type: prebuilt
pattern_name: br_cnpj
action: MASK
pattern_redaction_format: "[{pattern_name}_REDACTED]"
# --------------------------------------------------------------------------
# 3. CONTACT INFORMATION
# --------------------------------------------------------------------------
- guardrail_name: contact-information-pii
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# Email addresses (employees, contractors, suppliers)
- pattern_type: prebuilt
pattern_name: email
action: MASK
# Phone numbers (US format, commonly used internationally)
- pattern_type: prebuilt
pattern_name: us_phone
action: MASK
# Brazilian phones (if applicable)
- pattern_type: prebuilt
pattern_name: br_phone_landline
action: MASK
- pattern_type: prebuilt
pattern_name: br_phone_mobile
action: MASK
# Street addresses (mining sites, offices, residential)
- pattern_type: prebuilt
pattern_name: street_address
action: MASK
# Postal codes
- pattern_type: prebuilt
pattern_name: br_cep
action: MASK
pattern_redaction_format: "[{pattern_name}_REDACTED]"
# --------------------------------------------------------------------------
# 4. FINANCIAL & PAYMENT INFORMATION
# --------------------------------------------------------------------------
- guardrail_name: financial-pii
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# Credit cards (corporate cards, employee expenses)
- 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
# International banking (IBAN for international payments)
- pattern_type: prebuilt
pattern_name: iban
action: MASK
pattern_redaction_format: "[{pattern_name}_REDACTED]"
# --------------------------------------------------------------------------
# 5. CREDENTIALS & API KEYS (BLOCK - High Risk)
# --------------------------------------------------------------------------
- guardrail_name: credentials-api-keys
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# AWS credentials (critical infrastructure access)
- pattern_type: prebuilt
pattern_name: aws_access_key
action: BLOCK
- pattern_type: prebuilt
pattern_name: aws_secret_key
action: BLOCK
# GitHub tokens (code repository access)
- pattern_type: prebuilt
pattern_name: github_token
action: BLOCK
# Slack tokens (internal communications)
- pattern_type: prebuilt
pattern_name: slack_token
action: BLOCK
# Generic API keys
- pattern_type: prebuilt
pattern_name: generic_api_key
action: BLOCK
pattern_redaction_format: "[{pattern_name}_REDACTED]"
# --------------------------------------------------------------------------
# 6. NETWORK INFORMATION (Mining operations, remote sites)
# --------------------------------------------------------------------------
- guardrail_name: network-infrastructure-pii
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# IP addresses (internal network, mining site infrastructure)
- pattern_type: prebuilt
pattern_name: ipv4
action: MASK
- pattern_type: prebuilt
pattern_name: ipv6
action: MASK
pattern_redaction_format: "[INTERNAL_IP_REDACTED]"
# --------------------------------------------------------------------------
# 7. PROTECTED CLASS INFORMATION (Fair Lending, HR Compliance)
# Critical for mining industry with diverse workforce
# --------------------------------------------------------------------------
- guardrail_name: protected-class-information
litellm_params:
guardrail: litellm_content_filter
mode: pre_call
patterns:
# Gender and sexual orientation (workplace discrimination prevention)
- pattern_type: prebuilt
pattern_name: gender_sexual_orientation
action: MASK
# Race, ethnicity, national origin (diversity/inclusion compliance)
- pattern_type: prebuilt
pattern_name: race_ethnicity_national_origin
action: MASK
# Religion and creed
- pattern_type: prebuilt
pattern_name: religion
action: MASK
# Age discrimination (important for mining workforce management)
- pattern_type: prebuilt
pattern_name: age_discrimination
action: MASK
# Disability status (safety accommodations, worker's compensation)
- pattern_type: prebuilt
pattern_name: disability
action: MASK
# Marital and family status (relocation, benefits)
- pattern_type: prebuilt
pattern_name: marital_family_status
action: MASK
# Military status
- pattern_type: prebuilt
pattern_name: military_status
action: MASK
# Public assistance status
- pattern_type: prebuilt
pattern_name: public_assistance
action: MASK
pattern_redaction_format: "[PROTECTED_CLASS_INFO_REDACTED]"
# --------------------------------------------------------------------------
# 8. CUSTOM CODE GUARDRAIL - Mining Industry Specific PII
# --------------------------------------------------------------------------
- guardrail_name: mining-industry-custom-pii
litellm_params:
guardrail: custom_code
mode: pre_call
custom_code: |
def apply_guardrail(inputs, request_data, input_type):
"""
Custom PII detection for mining industry:
- Australian Company Numbers (ACN)
- Mining License Numbers
- Site-specific employee IDs
- Geological coordinates (sensitive mine locations)
"""
import re
for text in inputs["texts"]:
# Australian Company Number (ACN) - 9 digits, space-separated
# Format: XXX XXX XXX
acn_pattern = r'\b\d{3}\s\d{3}\s\d{3}\b'
if re.search(acn_pattern, text):
# Mask ACNs
text = re.sub(acn_pattern, '[ACN_REDACTED]', text)
# Mining tenement/license numbers (Australian format)
# Format: M/E/P + numbers (e.g., M12345, EL6789)
mining_license_pattern = r'\b[MEP][A-Z]?\s?\d{4,6}\b'
if re.search(mining_license_pattern, text, re.IGNORECASE):
text = re.sub(mining_license_pattern, '[MINING_LICENSE_REDACTED]', text, flags=re.IGNORECASE)
# Precise GPS coordinates (sensitive mine locations)
# Format: latitude, longitude with high precision
gps_pattern = r'-?\d{1,3}\.\d{4,}\s*,\s*-?\d{1,3}\.\d{4,}'
if re.search(gps_pattern, text):
text = re.sub(gps_pattern, '[GPS_COORDINATES_REDACTED]', text)
# FIFO/DIDO roster numbers or employee mining IDs
# Format: Common mining employee ID patterns
employee_id_pattern = r'\b(?:EMP|FIF|DID|MIN)[_-]?\d{5,8}\b'
if re.search(employee_id_pattern, text, re.IGNORECASE):
text = re.sub(employee_id_pattern, '[EMPLOYEE_ID_REDACTED]', text, flags=re.IGNORECASE)
# Update the text in inputs if any modifications were made
if text != inputs["texts"][inputs["texts"].index(inputs["texts"][next(i for i, t in enumerate(inputs["texts"]) if t == text)])]:
inputs["texts"][inputs["texts"].index(inputs["texts"][next(i for i, t in enumerate(inputs["texts"]) if t == text)])] = text
return allow()
# ==============================================================================
# POLICIES - Combining PII Guardrails
# ==============================================================================
policies:
# Comprehensive PII policy for Fortescue mining operations
fortescue-pii-protection:
description: >
Comprehensive PII detection and masking policy for Fortescue.
Protects Australian-specific identifiers, international employee data,
financial information, credentials, protected class information,
and mining industry-specific sensitive data.
guardrails:
add:
# Australian-specific
- au-pii-tax-identifiers
- au-pii-passports
# International workforce
- international-pii-identifiers
# Contact information
- contact-information-pii
# Financial data
- financial-pii
# Credentials (blocks instead of masks)
- credentials-api-keys
# Network infrastructure
- network-infrastructure-pii
# Protected class compliance
- protected-class-information
# Mining industry custom
- mining-industry-custom-pii
# Baseline policy for non-sensitive internal use
fortescue-pii-baseline:
description: >
Baseline PII protection for internal tools and testing.
Focuses on credentials and high-risk identifiers only.
guardrails:
add:
- au-pii-tax-identifiers
- credentials-api-keys
- financial-pii
# HR and recruiting policy (extra strict on protected class)
fortescue-pii-hr-recruiting:
description: >
Strict PII protection for HR, recruiting, and workforce management.
Emphasizes protected class information to ensure compliance with
anti-discrimination laws and workplace regulations.
inherit: fortescue-pii-protection
guardrails:
add:
# Already includes protected-class-information from parent
# This policy ensures all PII filters are active for HR use cases
# ==============================================================================
# POLICY ATTACHMENTS - Apply Policies to Teams/Keys/Models
# ==============================================================================
policy_attachments:
# Apply comprehensive PII protection globally
- policy: fortescue-pii-protection
scope: "*" # Applies to all requests by default
# Override for HR team with stricter policy
# Uncomment and modify team alias after creating teams
# - policy: fortescue-pii-hr-recruiting
# teams:
# - hr-team
# - recruiting-team
# - workforce-management
# Override for internal development/testing with baseline policy
# - policy: fortescue-pii-baseline
# teams:
# - internal-dev
# - testing-team
# keys:
# - dev-*
# - test-*

View file

@ -11,8 +11,10 @@ All /policy management endpoints
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
@ -34,6 +36,87 @@ 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. Raises on network/parse errors.
"""
response = httpx.get(url, timeout=timeout)
response.raise_for_status()
return response.json()
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()
# Try to fetch from GitHub
try:
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"Fetched policy templates is not a list (type={type(templates).__name__}). "
"Falling back to local backup."
)
return load_local_policy_templates()
if len(templates) == 0:
verbose_proxy_logger.warning(
"Fetched policy templates is empty. Falling back to local backup."
)
return load_local_policy_templates()
verbose_proxy_logger.debug(
f"Successfully fetched {len(templates)} policy templates from GitHub"
)
return templates
except Exception as e:
verbose_proxy_logger.warning(
f"Failed to fetch policy templates from {POLICY_TEMPLATES_GITHUB_URL}: {e}. "
"Falling back to local backup."
)
return load_local_policy_templates()
@router.post(
"/policy/validate",
tags=["policy management"],
@ -279,32 +362,15 @@ async def get_policy_templates(
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.
"""
try:
# Get the path to the policy_templates.json file
current_dir = os.path.dirname(os.path.abspath(__file__))
templates_path = os.path.join(
os.path.dirname(current_dir), "policy_templates.json"
)
# Read and return the templates
with open(templates_path, "r") as f:
templates = json.load(f)
templates = get_policy_templates_list()
verbose_proxy_logger.debug(f"Loaded {len(templates)} policy templates")
return templates
except FileNotFoundError:
raise HTTPException(
status_code=404,
detail="Policy templates file not found",
)
except json.JSONDecodeError as e:
verbose_proxy_logger.error(f"Error parsing policy templates JSON: {e}")
raise HTTPException(
status_code=500,
detail="Error parsing policy templates file",
)
except Exception as e:
verbose_proxy_logger.error(f"Error loading policy templates: {e}")
raise HTTPException(

230
policy_templates.json Normal file
View file

@ -0,0 +1,230 @@
[
{
"id": "advanced-au-pii-protection",
"title": "Advanced PII Protection (Australia)",
"description": "Comprehensive PII detection and masking for Australia. Protects Australian-specific identifiers, international employee data, financial information, credentials, protected class information, and industry-specific sensitive data.",
"icon": "ShieldCheckIcon",
"iconColor": "text-purple-500",
"iconBg": "bg-purple-50",
"guardrails": [
"au-pii-tax-identifiers",
"au-pii-passports",
"international-pii-identifiers",
"contact-information-pii",
"financial-pii",
"credentials-api-keys",
"network-infrastructure-pii",
"protected-class-information"
],
"complexity": "High",
"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": "au-pii-passports",
"litellm_params": {
"guardrail": "litellm_content_filter",
"mode": "pre_call",
"patterns": [
{
"pattern_type": "prebuilt",
"pattern_name": "passport_australia",
"action": "MASK"
}
],
"pattern_redaction_format": "[PASSPORT_REDACTED]"
},
"guardrail_info": {
"description": "Masks Australian passport numbers"
}
},
{
"guardrail_name": "international-pii-identifiers",
"litellm_params": {
"guardrail": "litellm_content_filter",
"mode": "pre_call",
"patterns": [
{"pattern_type": "prebuilt", "pattern_name": "us_ssn", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "us_ssn_no_dash", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_us", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_uk", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_germany", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_france", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_netherlands", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "nl_bsn_contextual", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_china", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_india", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_japan", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "passport_canada", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_cpf", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_cpf_unformatted", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_rg", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_cnpj", "action": "MASK"}
],
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
},
"guardrail_info": {
"description": "Masks international PII identifiers including passports and national IDs"
}
},
{
"guardrail_name": "contact-information-pii",
"litellm_params": {
"guardrail": "litellm_content_filter",
"mode": "pre_call",
"patterns": [
{"pattern_type": "prebuilt", "pattern_name": "email", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "us_phone", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_phone_landline", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_phone_mobile", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "street_address", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "br_cep", "action": "MASK"}
],
"pattern_redaction_format": "[{pattern_name}_REDACTED]"
},
"guardrail_info": {
"description": "Masks contact information including emails, phone numbers, and addresses"
}
},
{
"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"
}
},
{
"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": "network-infrastructure-pii",
"litellm_params": {
"guardrail": "litellm_content_filter",
"mode": "pre_call",
"patterns": [
{"pattern_type": "prebuilt", "pattern_name": "ipv4", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "ipv6", "action": "MASK"}
],
"pattern_redaction_format": "[INTERNAL_IP_REDACTED]"
},
"guardrail_info": {
"description": "Masks IP addresses in requests"
}
},
{
"guardrail_name": "protected-class-information",
"litellm_params": {
"guardrail": "litellm_content_filter",
"mode": "pre_call",
"patterns": [
{"pattern_type": "prebuilt", "pattern_name": "gender_sexual_orientation", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "race_ethnicity_national_origin", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "religion", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "age_discrimination", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "disability", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "marital_family_status", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "military_status", "action": "MASK"},
{"pattern_type": "prebuilt", "pattern_name": "public_assistance", "action": "MASK"}
],
"pattern_redaction_format": "[PROTECTED_CLASS_INFO_REDACTED]"
},
"guardrail_info": {
"description": "Masks protected class information for HR compliance and anti-discrimination"
}
}
],
"templateData": {
"policy_name": "advanced-pii-protection-australia",
"description": "Comprehensive PII detection and masking policy for Australia. Protects Australian-specific identifiers, international employee data, financial information, credentials, protected class information, and industry-specific sensitive data.",
"guardrails_add": [
"au-pii-tax-identifiers",
"au-pii-passports",
"international-pii-identifiers",
"contact-information-pii",
"financial-pii",
"credentials-api-keys",
"network-infrastructure-pii",
"protected-class-information"
],
"guardrails_remove": []
}
},
{
"id": "baseline-pii-protection",
"title": "Baseline PII Protection",
"description": "Baseline PII protection for internal tools and testing. Focuses on credentials and high-risk identifiers only. Suitable for non-sensitive internal use.",
"icon": "ShieldCheckIcon",
"iconColor": "text-blue-500",
"iconBg": "bg-blue-50",
"guardrails": [
"au-pii-tax-identifiers",
"credentials-api-keys",
"financial-pii"
],
"complexity": "Low",
"guardrailDefinitions": [],
"templateData": {
"policy_name": "baseline-pii-protection",
"description": "Baseline PII protection for internal tools and testing. Focuses on credentials and high-risk identifiers only.",
"guardrails_add": [
"au-pii-tax-identifiers",
"credentials-api-keys",
"financial-pii"
],
"guardrails_remove": []
}
}
]

View file

@ -41,7 +41,9 @@ const AddPolicyForm: React.FC<AddPolicyFormProps> = ({
const [availableModels, setAvailableModels] = useState<string[]>([]);
const { userId, userRole } = useAuthorized();
const isEditing = !!editingPolicy;
// Only consider it "editing" if editingPolicy has a policy_id (real existing policy)
// If editingPolicy is set but has no policy_id, it's just pre-filled data for a new policy (e.g., from a template)
const isEditing = !!editingPolicy?.policy_id;
useEffect(() => {
if (visible && editingPolicy) {

View file

@ -234,7 +234,7 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
// Pre-fill the add policy form with template data
setEditingPolicy(selectedTemplate.templateData as Policy);
setIsAddPolicyModalVisible(true);
setActiveTab(0); // Switch to Policies tab
setActiveTab(1); // Switch to Policies tab (now at index 1)
// Show success message
if (createdGuardrails.length > 0) {
@ -266,13 +266,46 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
<div className="w-full mx-auto flex-auto overflow-y-auto m-8 p-2">
<TabGroup index={activeTab} onIndexChange={setActiveTab}>
<TabList className="mb-4">
<Tab>Templates</Tab>
<Tab>Policies</Tab>
<Tab>Attachments</Tab>
<Tab>Policy Simulator</Tab>
<Tab>Templates</Tab>
</TabList>
<TabPanels>
<TabPanel>
<Alert
message="About Policies"
description={
<div>
<p className="mb-3">
Use policies to group guardrails and control which ones run for specific teams, keys, or models.
</p>
<p className="mb-2 font-semibold">Why use policies?</p>
<ul className="list-disc list-inside mb-3 space-y-1 ml-2">
<li>Enable/disable specific guardrails for teams, keys, or models</li>
<li>Group guardrails into a single policy</li>
<li>Inherit from existing policies and override what you need</li>
</ul>
<a
href="https://docs.litellm.ai/docs/proxy/guardrails/guardrail_policies"
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:text-blue-800 underline inline-block mt-1"
>
Learn more in the documentation →
</a>
</div>
}
type="info"
icon={<InfoCircleOutlined />}
showIcon
closable
className="mb-6"
/>
<PolicyTemplates onUseTemplate={handleUseTemplate} accessToken={accessToken} />
</TabPanel>
<TabPanel>
<Alert
message="About Policies"
@ -438,10 +471,6 @@ const PoliciesPanel: React.FC<PoliciesPanelProps> = ({
<TabPanel>
<PolicyTestPanel accessToken={accessToken} />
</TabPanel>
<TabPanel>
<PolicyTemplates onUseTemplate={handleUseTemplate} accessToken={accessToken} />
</TabPanel>
</TabPanels>
</TabGroup>
</div>