Security Best Practices
This guide covers security considerations for integrating with the Litmus API.
Authentication Security
API Key Management
- Never commit API keys to version control
- Use environment variables or secret management services
- Rotate keys periodically
- Use separate keys for development and production
# Good: Environment variable
export LITMUS_API_KEY="lk_abc123..."
# Bad: Hardcoded in source
api_key = "lk_abc123..." # Don't do this!Token Handling
- Store tokens securely (httpOnly cookies for web apps)
- Don't expose tokens in URLs or logs
- Implement token refresh before expiration
Webhook Security
Always Verify Signatures
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)🚫
Never skip signature verification! Without it, attackers can send fake webhook events to your server.
Use HTTPS
All webhook URLs must use HTTPS. We reject HTTP endpoints.
Validate Webhook Source
Optionally whitelist Litmus IP ranges (contact support for current list).
Data Security
Sensitive Data in Experiments
- Don't include proprietary compound structures in hypothesis text
- Use privacy settings (
delayed_12moorprivate) for sensitive work - Be aware that
openexperiments are publicly visible
Result Data
- Results may contain sensitive measurements
- Implement access controls in your systems
- Consider data retention policies
Infrastructure Security
Network Security
# Restrict outbound connections
LITMUS_API_BASE = "https://api.litmus.science"
# Don't allow user-controlled URLs for API callsRate Limiting
Implement your own rate limiting to prevent runaway costs:
from functools import wraps
import time
def rate_limit(max_per_minute: int):
calls = []
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
now = time.time()
calls[:] = [c for c in calls if now - c < 60]
if len(calls) >= max_per_minute:
raise Exception("Rate limit exceeded")
calls.append(now)
return func(*args, **kwargs)
return wrapper
return decorator
@rate_limit(100)
def submit_experiment(spec):
# ...Compliance Considerations
Data Residency
- API servers are located in the US
- Contact support for data residency requirements
Audit Logging
The API logs all authenticated requests. Request audit logs via support.
HIPAA / PHI
Litmus does not support experiments involving protected health information (PHI) or human subjects research.
Reporting Security Issues
Report security vulnerabilities to security@litmus.science.
We operate a responsible disclosure program and will acknowledge reports within 48 hours.