diff --git a/litellm/policy_templates_backup.json b/litellm/policy_templates_backup.json index 0798f345bb5..1659971d82a 100644 --- a/litellm/policy_templates_backup.json +++ b/litellm/policy_templates_backup.json @@ -2947,5 +2947,394 @@ "Content Safety" ], "estimated_latency_ms": 1 + }, + { + "id": "canadian-pii-protection", + "title": "Canadian PII Protection (PIPEDA)", + "description": "Protects Canadian personal identifiers under PIPEDA, Ontario FIPPA, and provincial privacy legislation. Masks Social Insurance Numbers (SIN), Ontario Health Insurance Plan (OHIP) numbers, Ontario driver's licence numbers, Canadian passport numbers, IRCC immigration documents, Canadian bank account routing information, postal codes, email addresses, phone numbers, and University of Toronto institutional identifiers (student/employee numbers, UTORid, TCard).", + "icon": "ShieldCheckIcon", + "iconColor": "text-red-500", + "iconBg": "bg-red-50", + "guardrails": [ + "ca-pii-government-identifiers", + "ca-pii-health-drivers", + "ca-pii-immigration", + "ca-pii-financial", + "ca-pii-contact-information", + "ca-pii-institutional-ids" + ], + "complexity": "Medium", + "guardrailDefinitions": [ + { + "guardrail_name": "ca-pii-government-identifiers", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "ca_sin", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "passport_canada", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks Canadian Social Insurance Numbers (SIN) and Canadian passport numbers" + } + }, + { + "guardrail_name": "ca-pii-health-drivers", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "ca_ohip", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "ca_on_drivers_licence", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks Ontario Health Insurance Plan (OHIP) numbers and Ontario driver's licence numbers" + } + }, + { + "guardrail_name": "ca-pii-immigration", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "ca_immigration_doc", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks IRCC immigration document numbers including UCI, work/study permits, and IMM references" + } + }, + { + "guardrail_name": "ca-pii-financial", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "ca_bank_account", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "credit_card", + "action": "MASK" + }, + { + "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": "iban", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks Canadian bank account routing information (transit-institution-account) and payment cards" + } + }, + { + "guardrail_name": "ca-pii-contact-information", + "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": "ca_postal_code", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks email addresses, phone numbers (North American format), and Canadian postal codes" + } + }, + { + "guardrail_name": "ca-pii-institutional-ids", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "uoft_student_id", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uoft_utorid", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uoft_tcard", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks University of Toronto institutional identifiers (student/employee numbers, UTORid login, TCard campus ID) under Ontario FIPPA" + } + } + ], + "templateData": { + "policy_name": "canadian-pii-protection", + "description": "Canadian PII protection policy under PIPEDA, Ontario FIPPA, and provincial privacy legislation. Masks SIN, OHIP, Ontario driver's licence, passport, IRCC immigration documents, bank account routing info, postal codes, email, phone numbers, and University of Toronto institutional identifiers.", + "guardrails_add": [ + "ca-pii-government-identifiers", + "ca-pii-health-drivers", + "ca-pii-immigration", + "ca-pii-financial", + "ca-pii-contact-information", + "ca-pii-institutional-ids" + ], + "guardrails_remove": [] + }, + "tags": [ + "PII Protection", + "Canada", + "PIPEDA", + "FIPPA" + ], + "estimated_latency_ms": 1 + }, + { + "id": "uk-pii-protection", + "title": "UK PII Protection (UK GDPR)", + "description": "Protects UK personal data under UK GDPR and the Data Protection Act 2018. Masks National Insurance Numbers, NHS numbers, driving licence numbers, Unique Taxpayer References, bank details, postcodes, phone numbers, and education identifiers.", + "icon": "ShieldCheckIcon", + "iconColor": "text-red-500", + "iconBg": "bg-red-50", + "guardrails": [ + "uk-pii-government-identifiers", + "uk-pii-health-drivers", + "uk-pii-financial", + "uk-pii-contact-information", + "uk-pii-education-identifiers" + ], + "complexity": "Medium", + "guardrailDefinitions": [ + { + "guardrail_name": "uk-pii-government-identifiers", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "uk_nino", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uk_utr", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "passport_uk", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks UK National Insurance Numbers, Unique Taxpayer References, and passport numbers" + } + }, + { + "guardrail_name": "uk-pii-health-drivers", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "uk_nhs_number", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uk_driving_licence", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks UK NHS numbers and DVLA driving licence numbers" + } + }, + { + "guardrail_name": "uk-pii-financial", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "uk_sort_code", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uk_bank_account", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "credit_card", + "action": "MASK" + }, + { + "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": "iban", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks UK sort codes, bank account numbers, and payment card and IBAN details" + } + }, + { + "guardrail_name": "uk-pii-contact-information", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "email", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uk_phone", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uk_postcode", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks email addresses, UK phone numbers, and postcodes" + } + }, + { + "guardrail_name": "uk-pii-education-identifiers", + "litellm_params": { + "guardrail": "litellm_content_filter", + "mode": "pre_call", + "patterns": [ + { + "pattern_type": "prebuilt", + "pattern_name": "uk_upn", + "action": "MASK" + }, + { + "pattern_type": "prebuilt", + "pattern_name": "uk_uln", + "action": "MASK" + } + ], + "pattern_redaction_format": "[{pattern_name}_REDACTED]" + }, + "guardrail_info": { + "description": "Masks Unique Pupil Numbers and Unique Learner Numbers" + } + } + ], + "templateData": { + "policy_name": "uk-pii-protection", + "description": "UK PII protection policy under UK GDPR and the Data Protection Act 2018. Masks National Insurance Numbers, NHS numbers, driving licences, Unique Taxpayer References, bank details, postcodes, phone numbers, and education identifiers.", + "guardrails_add": [ + "uk-pii-government-identifiers", + "uk-pii-health-drivers", + "uk-pii-financial", + "uk-pii-contact-information", + "uk-pii-education-identifiers" + ], + "guardrails_remove": [] + }, + "tags": [ + "PII Protection", + "Regulatory", + "UK", + "UK GDPR" + ], + "estimated_latency_ms": 1 } ] diff --git a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json index db6dd36726c..62219c5c585 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json +++ b/litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json @@ -624,6 +624,96 @@ "description": "Detects University of Toronto TCard campus ID card numbers (16-digit). Context keywords are critical to distinguish from payment card numbers.", "keyword_pattern": "\\b(?:tcard\\s*number|t-card\\s*number|tcard|t-card|campus\\s*card|campus\\s*id|university\\s*card)\\b", "allow_word_numbers": false + }, + { + "name": "uk_nino", + "display_name": "National Insurance Number (UK)", + "pattern": "\\b(?!BG|GB|KN|NK|NT|TN|ZZ)[A-CEGHJ-PR-TW-Z]{2}\\s?\\d{2}(?:\\s?\\d{2}){2}\\s?[A-D]\\b", + "category": "UK PII Patterns", + "description": "Detects UK National Insurance numbers with valid prefixes and suffixes", + "keyword_pattern": "\\b(?:national\\s*insurance\\s*number|national\\s*insurance|NI\\s*number|NI\\s*no\\.?|NINO)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_nhs_number", + "display_name": "NHS Number (UK)", + "pattern": "\\b(?:\\d{10}|\\d{3}([\\s-])\\d{3}\\1\\d{4})\\b", + "category": "UK PII Patterns", + "description": "Detects 10-digit UK NHS numbers in plain, spaced, or dashed format", + "keyword_pattern": "\\b(?:health\\s*service\\s*number|NHS\\s*number|NHS\\s*no\\.?|NHS)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_driving_licence", + "display_name": "Driving Licence Number (UK)", + "pattern": "\\b[A-Z9]{5}\\d{6}[A-Z9]{2}\\d[A-Z]{2}\\b", + "category": "UK PII Patterns", + "description": "Detects 16-character UK DVLA driving licence numbers", + "keyword_pattern": "\\b(?:driving\\s*licence\\s*number|driver'?s\\s*licence|driving\\s*licence|licence\\s*number|DVLA)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_utr", + "display_name": "Unique Taxpayer Reference (UK)", + "pattern": "\\b(?:\\d{10}|\\d{5}[-\\s]\\d{5})\\b", + "category": "UK PII Patterns", + "description": "Detects 10-digit UK Unique Taxpayer References", + "keyword_pattern": "\\b(?:unique\\s*taxpayer\\s*reference|self\\s*assessment|tax\\s*reference|HMRC|UTR)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_sort_code", + "display_name": "Sort Code (UK)", + "pattern": "\\b\\d{2}[-\\s]\\d{2}[-\\s]\\d{2}\\b", + "category": "UK PII Patterns", + "description": "Detects UK bank sort codes in NN-NN-NN format", + "keyword_pattern": "\\b(?:sort\\s*code|sort-code|bank\\s*sort)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_bank_account", + "display_name": "Bank Account Number (UK)", + "pattern": "\\b\\d{8}\\b", + "category": "UK PII Patterns", + "description": "Detects 8-digit UK bank account numbers", + "keyword_pattern": "\\b(?:bank\\s*account\\s*number|current\\s*account|account\\s*number|bank\\s*account|account\\s*no\\.?)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_postcode", + "display_name": "Postcode (UK)", + "pattern": "\\b(?:GIR\\s?0AA|(?:[A-PR-UWYZ][A-HK-Y]?\\d[A-Z\\d]?|[A-PR-UWYZ]\\d[A-HJKPSTUW]?))\\s?\\d[ABD-HJLNP-UW-Z]{2}\\b", + "category": "UK PII Patterns", + "description": "Detects UK postcodes with valid outward and inward code letter sets", + "keyword_pattern": "\\b(?:shipping\\s*address|mailing\\s*address|street\\s*address|home\\s*address|postal\\s*code|post\\s*code|postcode)\\b", + "allow_word_numbers": false + }, + { + "name": "uk_phone", + "display_name": "Phone Number (UK)", + "pattern": "(? ContentFilterGuardrail: + return ContentFilterGuardrail( + guardrail_name=f"test-{pattern_name}", + patterns=[ + ContentFilterPattern( + pattern_type="prebuilt", + pattern_name=pattern_name, + action=ContentFilterAction.MASK, + ) + ], + pattern_redaction_format="[{pattern_name}_REDACTED]", + ) + + +@pytest.mark.parametrize( + "pattern_name, keyword, valid_value", + UK_PATTERN_MATCH_CASES, +) +@pytest.mark.asyncio +async def test_uk_pii_value_with_keyword_is_masked( + pattern_name: str, + keyword: str, + valid_value: str, +) -> None: + guardrail: Final = _guardrail_for(pattern_name) + result: Final = await guardrail.apply_guardrail( + inputs={"texts": [f"{keyword}: {valid_value}"]}, + request_data={}, + input_type="request", + ) + output: Final = result["texts"][0] + + assert f"[{pattern_name.upper()}_REDACTED]" in output + assert valid_value not in output + + +@pytest.mark.parametrize( + "pattern_name, keyword, valid_value", + UK_PATTERN_MATCH_CASES, +) +@pytest.mark.asyncio +async def test_uk_pii_value_without_keyword_passes_unchanged( + pattern_name: str, + keyword: str, + valid_value: str, +) -> None: + guardrail: Final = _guardrail_for(pattern_name) + result: Final = await guardrail.apply_guardrail( + inputs={"texts": [valid_value]}, + request_data={}, + input_type="request", + ) + output: Final = result["texts"][0] + + assert output == valid_value + assert keyword.lower() not in output.lower() + + +@pytest.mark.parametrize( + "pattern_name, keyword, valid_value, invalid_value", + UK_PATTERN_CASES, +) +@pytest.mark.asyncio +async def test_invalid_uk_pii_format_passes_unchanged( + pattern_name: str, + keyword: str, + valid_value: str, + invalid_value: str, +) -> None: + guardrail: Final = _guardrail_for(pattern_name) + text: Final = f"{keyword}: {invalid_value}" + result: Final = await guardrail.apply_guardrail( + inputs={"texts": [text]}, + request_data={}, + input_type="request", + ) + output: Final = result["texts"][0] + + assert output == text + assert valid_value not in output + + +def test_uk_policy_templates_reference_available_prebuilt_patterns() -> None: + patterns_file: Final = REPO_ROOT / "litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/patterns.json" + pattern_names: Final = { + pattern["name"] for pattern in json.loads(patterns_file.read_text())["patterns"] + } + policy_files: Final = ( + REPO_ROOT / "policy_templates.json", + REPO_ROOT / "litellm/policy_templates_backup.json", + ) + policy_templates: Final = tuple( + json.loads(policy_file.read_text()) for policy_file in policy_files + ) + uk_templates: Final = tuple( + next(template for template in templates if template["id"] == "uk-pii-protection") + for templates in policy_templates + ) + backup_ids: Final = {template["id"] for template in policy_templates[1]} + + assert "canadian-pii-protection" in backup_ids + for template in uk_templates: + for guardrail in template["guardrailDefinitions"]: + for pattern in guardrail["litellm_params"]["patterns"]: + if pattern["pattern_type"] == "prebuilt": + assert pattern["pattern_name"] in pattern_names diff --git a/tests/unit/proxy/guardrails/guardrail_hooks/content_filter/test_uk_policy_e2e.py b/tests/unit/proxy/guardrails/guardrail_hooks/content_filter/test_uk_policy_e2e.py new file mode 100644 index 00000000000..564c7a47928 --- /dev/null +++ b/tests/unit/proxy/guardrails/guardrail_hooks/content_filter/test_uk_policy_e2e.py @@ -0,0 +1,117 @@ +import json +from itertools import chain +from pathlib import Path +from typing import Final + +import pytest + +from litellm.proxy.guardrails.guardrail_hooks.litellm_content_filter.content_filter import ( + ContentFilterGuardrail, +) +from litellm.types.guardrails import ContentFilterAction, ContentFilterPattern + +REPO_ROOT: Final = Path(__file__).resolve().parents[6] +UK_TEMPLATE_PATTERN_NAMES: Final = ( + "uk_nino", + "uk_utr", + "passport_uk", + "uk_nhs_number", + "uk_driving_licence", + "uk_sort_code", + "uk_bank_account", + "credit_card", + "visa", + "mastercard", + "amex", + "iban", + "email", + "uk_phone", + "uk_postcode", + "uk_upn", + "uk_uln", +) + +UK_PII_CASES: Final = ( + ("National Insurance Number: AB 12 34 56 C", "AB 12 34 56 C", "[UK_NINO_REDACTED]"), + ("Unique Taxpayer Reference: 12345 67890", "12345 67890", "[UK_UTR_REDACTED]"), + ("UK passport number: 123456789", "123456789", "[PASSPORT_UK_REDACTED]"), + ("NHS number: 943 476 5919", "943 476 5919", "[UK_NHS_NUMBER_REDACTED]"), + ("Driving licence number: ABCDE123456AB1CD", "ABCDE123456AB1CD", "[UK_DRIVING_LICENCE_REDACTED]"), + ("Sort code: 12-34-56", "12-34-56", "[UK_SORT_CODE_REDACTED]"), + ("Bank account number: 12345678", "12345678", "[UK_BANK_ACCOUNT_REDACTED]"), + ("Credit card number: 4111111111111111", "4111111111111111", "[CREDIT_CARD_REDACTED]"), + ("Visa card number: 4111111111111111", "4111111111111111", "[CREDIT_CARD_REDACTED]"), + ("Mastercard number: 5555555555554444", "5555555555554444", "[CREDIT_CARD_REDACTED]"), + ("Amex card number: 378282246310005", "378282246310005", "[CREDIT_CARD_REDACTED]"), + ("IBAN: GB82WEST12345698765432", "GB82WEST12345698765432", "[IBAN_REDACTED]"), + ("Email: person@example.com", "person@example.com", "[EMAIL_REDACTED]"), + ("Mobile number: 07911 123456", "07911 123456", "[UK_PHONE_REDACTED]"), + ("Postcode: SW1A 1AA", "SW1A 1AA", "[UK_POSTCODE_REDACTED]"), + ("Unique pupil number: A123456789012", "A123456789012", "[UK_UPN_REDACTED]"), + ("Unique learner number: 1234567890", "1234567890", "[UK_ULN_REDACTED]"), +) + + +def test_full_pipeline_covers_all_template_patterns() -> None: + policy_templates: Final = json.loads((REPO_ROOT / "policy_templates.json").read_text()) + uk_template: Final = next( + template for template in policy_templates if template["id"] == "uk-pii-protection" + ) + guardrail_patterns: Final = tuple( + guardrail["litellm_params"]["patterns"] + for guardrail in uk_template["guardrailDefinitions"] + ) + template_pattern_names: Final = tuple( + pattern["pattern_name"] for pattern in chain.from_iterable(guardrail_patterns) + ) + + assert template_pattern_names == UK_TEMPLATE_PATTERN_NAMES + + +class TestUKPIIPolicyE2E: + def setup_uk_guardrail(self) -> ContentFilterGuardrail: + patterns: Final = [ + ContentFilterPattern( + pattern_type="prebuilt", + pattern_name=pattern_name, + action=ContentFilterAction.MASK, + ) + for pattern_name in UK_TEMPLATE_PATTERN_NAMES + ] + + return ContentFilterGuardrail( + guardrail_name="uk-pii-protection", + patterns=patterns, + pattern_redaction_format="[{pattern_name}_REDACTED]", + ) + + @pytest.mark.parametrize( + "text, sensitive_value, redaction", + UK_PII_CASES, + ids=tuple(f"case-{index}" for index in range(len(UK_PII_CASES))), + ) + @pytest.mark.asyncio + async def test_template_pii_is_masked(self, text: str, sensitive_value: str, redaction: str) -> None: + guardrail: Final = self.setup_uk_guardrail() + result: Final = await guardrail.apply_guardrail( + inputs={"texts": [text]}, + request_data={}, + input_type="request", + ) + output: Final = result["texts"][0] + + assert redaction in output + assert sensitive_value not in output + + @pytest.mark.asyncio + async def test_clean_prompt_passes_unchanged(self) -> None: + guardrail: Final = self.setup_uk_guardrail() + text: Final = "How do I update my address with the local council?" + result: Final = await guardrail.apply_guardrail( + inputs={"texts": [text]}, + request_data={}, + input_type="request", + ) + output: Final = result["texts"][0] + + assert output == text diff --git a/ui/litellm-dashboard/src/data/compliancePrompts.ts b/ui/litellm-dashboard/src/data/compliancePrompts.ts index 35948b56e9e..6e79a8930e5 100644 --- a/ui/litellm-dashboard/src/data/compliancePrompts.ts +++ b/ui/litellm-dashboard/src/data/compliancePrompts.ts @@ -2,6 +2,7 @@ import { insultsCompliancePrompts } from "./insultsCompliancePrompts"; import { financialCompliancePrompts } from "./financialCompliancePrompts"; import { codeExecutionCompliancePrompts } from "./codeExecutionCompliancePrompts"; import { canadianPiiCompliancePrompts } from "./canadianPiiCompliancePrompts"; +import { ukPiiCompliancePrompts } from "./ukPiiCompliancePrompts"; import { claimsCompliancePrompts } from "./claimsCompliancePrompts"; export interface CompliancePrompt { @@ -260,6 +261,7 @@ const compliancePrompts: CompliancePrompt[] = [ ...financialCompliancePrompts, ...codeExecutionCompliancePrompts, ...canadianPiiCompliancePrompts, + ...ukPiiCompliancePrompts, ...claimsCompliancePrompts, ]; @@ -546,6 +548,11 @@ const frameworkMeta: Record = { description: "Ontario FIPPA institutional identifier detection — masks University of Toronto student/employee numbers, UTORid logins, and TCard campus IDs.", }, + "UK PII (UK GDPR)": { + icon: "shield", + description: + "UK GDPR and Data Protection Act 2018 detection — masks National Insurance Numbers, NHS numbers, driving licences, tax references, financial details, contact information, and education identifiers.", + }, "Airline Brand Protection": { icon: "plane", description: "Destination vs competitor intent — avoid answering competitor comparison questions.", diff --git a/ui/litellm-dashboard/src/data/ukPiiCompliancePrompts.ts b/ui/litellm-dashboard/src/data/ukPiiCompliancePrompts.ts new file mode 100644 index 00000000000..10ed3f63ac9 --- /dev/null +++ b/ui/litellm-dashboard/src/data/ukPiiCompliancePrompts.ts @@ -0,0 +1,154 @@ +import type { CompliancePrompt } from "./compliancePrompts"; + +export const ukPiiCompliancePrompts: CompliancePrompt[] = [ + { + id: "uk-nino-1", + framework: "UK PII (UK GDPR)", + category: "National Insurance Number", + categoryIcon: "shield", + categoryDescription: + "Detects UK National Insurance Numbers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My National Insurance number is AB 12 34 56 C.", + expectedResult: "fail", + }, + { + id: "uk-utr-1", + framework: "UK PII (UK GDPR)", + category: "Government Identifiers", + categoryIcon: "shield", + categoryDescription: + "Detects UK Unique Taxpayer References protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My Unique Taxpayer Reference is 12345 67890.", + expectedResult: "fail", + }, + { + id: "uk-government-3", + framework: "UK PII (UK GDPR)", + category: "Government Identifiers", + categoryIcon: "shield", + categoryDescription: + "Detects UK government identifiers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "How do I apply for a National Insurance number?", + expectedResult: "pass", + }, + { + id: "uk-nhs-1", + framework: "UK PII (UK GDPR)", + category: "Health and Driving Identifiers", + categoryIcon: "heart", + categoryDescription: + "Detects NHS numbers and DVLA driving licence numbers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My NHS number is 943 476 5919.", + expectedResult: "fail", + }, + { + id: "uk-driving-1", + framework: "UK PII (UK GDPR)", + category: "Health and Driving Identifiers", + categoryIcon: "credit-card", + categoryDescription: + "Detects driving licence numbers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My driving licence number is ABCDE123456AB1CD.", + expectedResult: "fail", + }, + { + id: "uk-health-3", + framework: "UK PII (UK GDPR)", + category: "Health and Driving Identifiers", + categoryIcon: "heart", + categoryDescription: + "Covers sensitive health and driving identifiers under UK GDPR and the Data Protection Act 2018.", + prompt: "How can I request a replacement NHS card?", + expectedResult: "pass", + }, + { + id: "uk-sort-code-1", + framework: "UK PII (UK GDPR)", + category: "Financial Information", + categoryIcon: "dollar-sign", + categoryDescription: + "Detects UK sort codes and bank account numbers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My sort code is 12-34-56 and my account number is 12345678.", + expectedResult: "fail", + }, + { + id: "uk-financial-2", + framework: "UK PII (UK GDPR)", + category: "Financial Information", + categoryIcon: "dollar-sign", + categoryDescription: + "Detects payment card and IBAN details protected under UK GDPR and the Data Protection Act 2018.", + prompt: "Please charge my Visa card 4111 1111 1111 1111.", + expectedResult: "fail", + }, + { + id: "uk-financial-3", + framework: "UK PII (UK GDPR)", + category: "Financial Information", + categoryIcon: "dollar-sign", + categoryDescription: + "Covers financial information under UK GDPR and the Data Protection Act 2018.", + prompt: "How do I find the sort code for a UK bank?", + expectedResult: "pass", + }, + { + id: "uk-contact-1", + framework: "UK PII (UK GDPR)", + category: "Contact Information", + categoryIcon: "map-pin", + categoryDescription: + "Detects email addresses, UK phone numbers, and postcodes protected under UK GDPR and the Data Protection Act 2018.", + prompt: "Call me on 07911 123456 and post this to SW1A 1AA.", + expectedResult: "fail", + }, + { + id: "uk-contact-2", + framework: "UK PII (UK GDPR)", + category: "Contact Information", + categoryIcon: "map-pin", + categoryDescription: + "Detects contact information protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My email address is person@example.com.", + expectedResult: "fail", + }, + { + id: "uk-contact-3", + framework: "UK PII (UK GDPR)", + category: "Contact Information", + categoryIcon: "map-pin", + categoryDescription: + "Covers personal contact details under UK GDPR and the Data Protection Act 2018.", + prompt: "What is the format of a UK postcode?", + expectedResult: "pass", + }, + { + id: "uk-upn-1", + framework: "UK PII (UK GDPR)", + category: "Education Identifiers", + categoryIcon: "graduation-cap", + categoryDescription: + "Detects Unique Pupil Numbers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "The pupil's UPN is A123456789012.", + expectedResult: "fail", + }, + { + id: "uk-uln-1", + framework: "UK PII (UK GDPR)", + category: "Education Identifiers", + categoryIcon: "graduation-cap", + categoryDescription: + "Detects Unique Learner Numbers protected under UK GDPR and the Data Protection Act 2018.", + prompt: "My Unique Learner Number is 1234567890.", + expectedResult: "fail", + }, + { + id: "uk-education-3", + framework: "UK PII (UK GDPR)", + category: "Education Identifiers", + categoryIcon: "graduation-cap", + categoryDescription: + "Covers education identifiers under UK GDPR and the Data Protection Act 2018.", + prompt: "How do I request my pupil records?", + expectedResult: "pass", + }, +];