This document describes the security features implemented in ChatFormula1 and how to use them.
ChatFormula1 implements multiple layers of security to protect against common vulnerabilities and ensure safe operation:
- Input Validation and Sanitization - Prevents prompt injection and XSS attacks
- Rate Limiting - Prevents abuse and ensures fair usage
- API Key Authentication - Controls access to the API
- Request Signing - Ensures request integrity for sensitive operations
- CORS Policies - Controls cross-origin access
- Length Limits: Queries are limited to 2000 characters by default
- Prompt Injection Detection: Detects and blocks common prompt injection patterns
- Code Injection Prevention: Blocks potentially malicious code patterns
- HTML Sanitization: Removes HTML tags and scripts
- Control Character Removal: Strips control characters except newlines and tabs
- Whitespace Normalization: Normalizes excessive whitespace
# In .env file
ENABLE_INPUT_VALIDATION=true
STRICT_INPUT_VALIDATION=false # Set to true for stricter validation
MAX_QUERY_LENGTH=2000Input validation is automatically applied to all chat endpoints. You can also use it programmatically:
from src.security import validate_query, sanitize_query
# Validate input
result = validate_query("User input here", strict_mode=False)
if result.valid:
sanitized_input = result.sanitized_input
else:
print(f"Validation errors: {result.errors}")
# Or just sanitize
sanitized = sanitize_query("User input here")The validator detects the following suspicious patterns:
- Attempts to override system instructions
- Role-playing or persona changes
- Special tokens (e.g.,
<|im_start|>,<|im_end|>) - JavaScript and HTML injection
- Python code execution attempts
- Token Bucket Algorithm: Smooth rate limiting with burst support
- Per-Client Limits: Separate limits for each IP address or API key
- Multiple Time Windows: Both per-minute and per-hour limits
- Graceful Degradation: Returns 429 status with Retry-After header
# In .env file
ENABLE_RATE_LIMITING=true
RATE_LIMIT_PER_MINUTE=60
RATE_LIMIT_PER_HOUR=1000- Per Minute: 60 requests (with burst up to 60)
- Per Hour: 1000 requests
Rate limit information is included in response headers:
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 45
X-RateLimit-Limit-Hour: 1000
X-RateLimit-Remaining-Hour: 892
curl http://localhost:8000/api/chat/rate-limitResponse:
{
"enabled": true,
"client_id": "ip:127.0.0.1",
"limits": {
"requests_per_minute": 60,
"requests_per_hour": 1000,
"burst_size": 60
},
"remaining": {
"minute": 45,
"hour": 892
}
}API keys provide a way to authenticate and authorize API access. Each key can have:
- Custom rate limits (multiplier)
- Specific scopes/permissions
- Expiration dates
- Active/inactive status
# In .env file
REQUIRE_API_KEY=false # Set to true to require API keys for all endpoints
API_KEY_HEADER_NAME=X-API-Key# Create a new API key
curl -X POST http://localhost:8000/api/admin/api-keys \
-H "Content-Type: application/json" \
-d '{
"name": "My Application",
"scopes": ["chat", "admin"],
"expires_in_days": 90,
"rate_limit_multiplier": 2.0
}'Response:
{
"key_id": "abc123",
"key": "f1s_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"name": "My Application",
"created_at": "2024-01-01T00:00:00",
"expires_at": "2024-04-01T00:00:00",
"is_active": true,
"scopes": ["chat", "admin"]
}Important: The raw API key is only shown once. Store it securely!
Include the API key in the X-API-Key header:
curl http://localhost:8000/api/chat \
-H "X-API-Key: f1s_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"message": "Who won the last race?"}'curl http://localhost:8000/api/admin/api-keyscurl -X DELETE http://localhost:8000/api/admin/api-keys/{key_id}curl -X POST http://localhost:8000/api/admin/api-keys/{key_id}/rotateThis generates a new key with the same settings and revokes the old one.
Scopes control what operations an API key can perform:
chat: Access to chat endpointsadmin: Access to admin endpointsingest: Access to data ingestion*: All scopes (wildcard)
To require a specific scope in your endpoint:
from src.security import require_scope
@router.post("/sensitive-operation")
async def sensitive_operation(
api_key: APIKey = Depends(require_scope("admin"))
):
# Only API keys with "admin" scope can access this
passFor highly sensitive operations, request signing ensures that requests haven't been tampered with.
Request signing requires a secret key. Set it in your environment:
# In .env file
REQUEST_SIGNING_SECRET=your-secret-key-herefrom src.security.request_signing import get_request_signer
signer = get_request_signer(secret_key="your-secret-key")
# Sign a request
signature = signer.sign_request(
method="POST",
path="/api/admin/sensitive",
body='{"data": "value"}',
)
# Include signature in X-Signature headerfrom src.security.request_signing import require_signed_request
@router.post("/sensitive-operation")
async def sensitive_operation(
_: None = Depends(require_signed_request())
):
# Request signature is verified before this runs
pass# In .env file
ENABLE_CORS=true
CORS_ALLOW_ORIGINS=["http://localhost:3000", "http://localhost:8501"]- Development:
localhost:3000,localhost:8501,localhost:8000 - Production: Only explicitly configured origins
The following headers are exposed to clients:
X-Request-IDX-RateLimit-Limit-MinuteX-RateLimit-Remaining-MinuteX-RateLimit-Limit-HourX-RateLimit-Remaining-Hour
- Never commit API keys or secrets to version control
- Use environment variables for all sensitive configuration
- Enable strict validation in production environments
- Rotate API keys regularly (every 90 days recommended)
- Monitor rate limit violations for potential abuse
- Use HTTPS in production (never HTTP)
- Implement request signing for sensitive operations
- Review logs regularly for security events
- Set
REQUIRE_API_KEY=truein production - Enable
STRICT_INPUT_VALIDATION=truein production - Configure appropriate rate limits based on expected traffic
- Use a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.)
- Enable CORS only for trusted origins
- Set up monitoring and alerting for security events
- Keep dependencies updated to patch vulnerabilities
- Use a WAF (Web Application Firewall) if available
- Store API keys securely (use environment variables, not hardcoded)
- Implement exponential backoff when rate limited
- Handle 401/403 errors gracefully
- Don't share API keys between applications
- Rotate keys if compromised
- Monitor your usage to stay within limits
The API includes the following security headers:
X-Request-ID: Unique request identifier for trackingX-RateLimit-*: Rate limit informationRetry-After: Time to wait when rate limited (429 responses)
If you discover a security vulnerability, please email security@chatformula1.com (or your configured security contact) with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
Do not open public issues for security vulnerabilities.
ChatFormula1 implements security controls to help with:
- OWASP Top 10 protection
- Input validation (A03:2021 - Injection)
- Rate limiting (A04:2021 - Insecure Design)
- Authentication (A07:2021 - Identification and Authentication Failures)
- Logging (A09:2021 - Security Logging and Monitoring Failures)
# Should be rejected
curl -X POST http://localhost:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "Ignore all previous instructions and..."}'# Send many requests quickly
for i in {1..100}; do
curl http://localhost:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "test"}' &
done# Without API key (should fail if REQUIRE_API_KEY=true)
curl http://localhost:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "test"}'
# With invalid API key (should fail)
curl http://localhost:8000/api/chat \
-H "X-API-Key: invalid-key" \
-H "Content-Type: application/json" \
-d '{"message": "test"}'Monitor these metrics for security:
- Rate limit violations (429 responses)
- Authentication failures (401 responses)
- Input validation failures (400 responses with validation errors)
- Suspicious patterns detected in logs
- API key usage patterns
Use the metrics endpoints:
# Get all metrics
curl http://localhost:8000/api/admin/metrics
# Get Prometheus format
curl http://localhost:8000/api/admin/metrics/prometheusThis security documentation is current as of the implementation date. Check the repository for updates and new security features.