1 min read
Securing AI Applications: A Comprehensive 2025 Checklist
I wrote “Securing AI Applications: A Comprehensive 2025 Checklist” to share practical, production-minded guidance on this topic.
1. Input Validation and Sanitization
Prompt injection remains the top AI security risk:
import re
from typing import Optional
class PromptSanitizer:
DANGEROUS_PATTERNS = [
r"ignore previous instructions",
r"disregard all prior",
r"you are now",
r"pretend you are",
r"act as if",
r"system:\s*",
]
def __init__(self, max_length: int = 4000):
self.max_length = max_length
self.patterns = [re.compile(p, re.IGNORECASE) for p in self.DANGEROUS_PATTERNS]
def sanitize(self, user_input: str) -> tuple[str, list[str]]:
warnings = []
# Length check
if len(user_input) > self.max_length:
user_input = user_input[:self.max_length]
warnings.append("Input truncated to maximum length")
# Pattern detection
for pattern in self.patterns:
if pattern.search(user_input):
warnings.append(f"Potentially dangerous pattern detected")
user_input = pattern.sub("[FILTERED]", user_input)
return user_input, warnings
sanitizer = PromptSanitizer()
clean_input, warnings = sanitizer.sanitize(user_input)
2. Output Filtering
Prevent sensitive data leakage:
class OutputFilter:
def __init__(self):
self.pii_patterns = {
"ssn": r"\b\d{3}-\d{2}-\d{4}\b",
"credit_card": r"\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b",
"email": r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b",
}
def filter_response(self, response: str) -> str:
for pii_type, pattern in self.pii_patterns.items():
response = re.sub(pattern, f"[{pii_type.upper()}_REDACTED]", response)
return response
3. Rate Limiting and Quotas
from azure.appconfiguration import AzureAppConfigurationClient
import redis
class AIRateLimiter:
def __init__(self, redis_client: redis.Redis):
self.redis = redis_client
self.limits = {
"free": {"requests_per_minute": 10, "tokens_per_day": 10000},
"pro": {"requests_per_minute": 60, "tokens_per_day": 100000},
}
async def check_limit(self, user_id: str, tier: str) -> bool:
key = f"rate_limit:{user_id}"
current = self.redis.incr(key)
if current == 1:
self.redis.expire(key, 60)
return current <= self.limits[tier]["requests_per_minute"]
4. Audit Logging
import structlog
from datetime import datetime
logger = structlog.get_logger()
async def log_ai_interaction(
user_id: str,
prompt: str,
response: str,
model: str,
tokens_used: int
):
await logger.ainfo(
"ai_interaction",
user_id=user_id,
prompt_hash=hashlib.sha256(prompt.encode()).hexdigest(),
response_length=len(response),
model=model,
tokens_used=tokens_used,
timestamp=datetime.utcnow().isoformat()
)
Security Checklist
- Input sanitization for prompt injection
- Output filtering for PII
- Rate limiting per user/tier
- Comprehensive audit logging
- Model access controls (Azure RBAC)
- Data encryption at rest and in transit
- Regular security assessments
- Incident response procedures
- Content moderation filters
- Human review for high-risk outputs
AI security is not optional. Implement these measures before going to production, and review them quarterly as threats evolve.\n\n## Takeaways\n\nAdd a concise, personal takeaway and recommended next steps here.\n