The Code Interpreter API implements multiple layers of security to ensure safe code execution and protect against common web application vulnerabilities.
All API endpoints (except health checks and documentation) require authentication using an API key.
The API key can be provided in two ways:
-
x-api-key header (recommended):
curl -H "x-api-key: your-api-key" https://api.example.com/sessions -
Authorization header:
curl -H "Authorization: Bearer your-api-key" https://api.example.com/sessions
Set the API key in your environment:
export API_KEY="your-secure-api-key-here"Or in your .env file:
API_KEY=your-secure-api-key-here
Important: Use a strong, randomly generated API key in production.
The API implements rate limiting to prevent abuse:
- Authentication failures: Max 10 failed attempts per IP per hour
- API key validation: Results are cached for 5 minutes to improve performance
- Request rate limiting: Additional rate limiting can be configured per endpoint
All responses include security headers:
X-Content-Type-Options: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=blockStrict-Transport-Security: max-age=31536000; includeSubDomainsContent-Security-Policy: default-src 'self'(varies by endpoint)Referrer-Policy: strict-origin-when-cross-originPermissions-Policy: geolocation=(), microphone=(), camera=()
- Content-Type validation: Only allowed content types are accepted
- Request size limits: Configurable maximum request size
- Input sanitization: All user inputs are validated and sanitized
Uploaded files are validated for:
- Path traversal prevention:
../and\characters are blocked - Null byte injection: Null bytes in filenames are rejected
- File extension whitelist: Only allowed file extensions are accepted
- Filename length limits: Maximum 255 characters
- Suspicious characters: Special characters that could be dangerous are blocked
.txt, .csv, .json, .xml, .yaml, .yml,
.py, .js, .ts, .go, .java, .c, .cpp, .h, .hpp,
.rs, .php, .rb, .r, .f90, .d,
.md, .rst, .html, .css,
.png, .jpg, .jpeg, .gif, .svg,
.pdf, .doc, .docx, .xls, .xlsx
Code is analyzed for potentially dangerous patterns:
- System imports:
import os,import subprocess, etc. - Dangerous functions:
eval(),exec(),__import__(), etc. - File operations:
open(),file(), etc. - Input functions:
input(),raw_input(), etc.
Note: Dangerous patterns generate warnings but don't block execution, as the code runs in isolated Kubernetes pods.
- Kubernetes pods: All code runs in isolated Kubernetes pods
- Resource limits: Memory and CPU limits enforced via Kubernetes
- Network isolation: NetworkPolicy denies all egress by default
- Security context: Pods run as non-root (
runAsUser: 65532) - Ephemeral execution: Pods destroyed immediately after execution
Each execution pod runs a single container with an embedded Go runner binary. The runner executes code via subprocess within the same container. This design requires zero elevated privileges.
Pod Settings:
spec:
containers:
- name: execution
securityContext:
runAsUser: 65532
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]Why This Is Secure:
-
Zero elevated privileges: No
SYS_PTRACE,SYS_ADMIN,SYS_CHROOTcapabilities. NoallowPrivilegeEscalation. NoshareProcessNamespace. -
Single cgroup: User code runs in the same container as the runner, so Kubernetes resource limits (CPU, memory) apply directly to user code with no cgroup mismatch.
-
Non-root execution: The container runs as non-root (
runAsUser: 65532). -
No host namespace access: No capabilities that could be used to access host processes or namespaces.
-
Hardened runtime compatible: The zero-privilege model is compatible with any hardened Kubernetes runtime (gVisor, Kata Containers, etc.).
Execution pods are hardened to prevent information leakage about the host infrastructure. This prevents reconnaissance attacks that could reveal details about your cloud provider, Kubernetes cluster, or internal network configuration.
Currently Implemented:
| Feature | Protection |
|---|---|
| Generic hostname | All pods use hostname "sandbox" instead of revealing node info |
| Non-root execution | Pods run as runAsUser: 65532 with runAsNonRoot: true |
| Network policies | Egress denied by default, blocks cloud metadata endpoints |
| Public DNS only | Execution pods use only public DNS (8.8.8.8, 1.1.1.1) |
Note: Kernel version (/proc/version) and CPU/memory info (/proc/cpuinfo, /proc/meminfo)
remain accessible because many libraries depend on them. The pod security context and network
policies address the primary concern of revealing cloud provider and internal network details.
Execution pods are isolated via Kubernetes NetworkPolicy:
# In helm values.yaml
execution:
networkPolicy:
enabled: true # Enable NetworkPolicy enforcement
denyEgress: true # Block all egress (default: true)-
Full Isolation (default):
denyEgress: true- Blocks all outbound connections
- Pods cannot access internet or cluster services
- Maximum security for untrusted code
-
Selective Egress:
denyEgress: false- Allows DNS (UDP 53) and HTTPS (TCP 443/80)
- Enables package downloads (pip, npm, etc.)
- Note: Does not block private IP ranges
-
NetworkPolicy Required: Your Kubernetes cluster must have a CNI that supports NetworkPolicy (Calico, Cilium, etc.).
-
Default Deny: All egress is blocked by default for maximum security.
-
No Inter-Pod Communication: NetworkPolicy denies all ingress from other pods.
Python state persistence introduces additional security considerations:
- Serialization inside pods: State is serialized within the isolated execution pod, not on the API server. The API never unpickles user data.
- cloudpickle usage: We use cloudpickle for serialization. While pickle-based formats can execute code during deserialization, this only occurs inside the sandboxed pod.
- Compression: State is compressed with lz4 before storage, providing minor obfuscation and reducing attack surface.
- Base64 encoding: Final storage uses base64 encoding for safe transport.
- Redis encryption: Consider enabling Redis TLS in production for encrypted state storage
- MinIO encryption: Enable server-side encryption for archived states
- TTL-based cleanup: States automatically expire (2 hours in Redis, 7 days in MinIO archives)
- Size limits:
STATE_MAX_SIZE_MBprevents denial-of-service via large states
- Session binding: State is bound to
session_id, not directly accessible by other sessions - User scoping: Sessions are scoped by
user_idandentity_id - No cross-session access: One user's session cannot access another user's state
If state persistence poses unacceptable risk for your use case:
STATE_PERSISTENCE_ENABLED=falseThis ensures each execution starts with a clean namespace.
State persistence operations are logged:
- State save (size, session_id)
- State load (session_id, source: redis/minio)
- State archive (session_id)
- State size limit exceeded (warning)
All security-relevant events are logged:
- Authentication attempts: Success and failure
- File operations: Upload, download, delete
- Code execution: Language, warnings, success/failure
- Rate limiting: When limits are exceeded
{
"event_type": "authentication",
"success": true,
"api_key_prefix": "abc123...",
"client_ip": "192.168.1.100",
"endpoint": "GET /sessions",
"timestamp": "2024-01-15T10:30:00Z"
}- Authentication stats: Get authentication failure statistics
- Rate limit status: Check current rate limit status
- Security events: Query recent security events
# API Key (required)
API_KEY=your-secure-api-key
# Resource Limits
MAX_EXECUTION_TIME=30 # seconds
MAX_MEMORY_MB=512 # megabytes
MAX_FILE_SIZE_MB=10 # megabytes per file
MAX_FILES_PER_SESSION=50 # files per session
MAX_OUTPUT_FILES=10 # output files per execution
# Redis for caching and rate limiting
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=optional-password- Use strong API keys: Generate cryptographically secure random keys
- Enable HTTPS: Always use HTTPS in production
- Monitor logs: Regularly review security logs for suspicious activity
- Update dependencies: Keep all dependencies up to date
- Network isolation: Deploy in a private network when possible
- Resource monitoring: Monitor resource usage and set appropriate limits
If you see repeated authentication failures:
- Check the source IP in logs
- Verify the API key is correct
- Consider blocking suspicious IPs at the network level
- Rotate API keys if compromise is suspected
If dangerous code patterns are detected:
- Review the code content in logs
- Check the session and user context
- Consider additional code validation rules
- Monitor pod resource usage via Kubernetes metrics
For suspicious file uploads:
- Check filename validation logs
- Review file content if necessary
- Verify file size and type restrictions
- Monitor storage usage
This security documentation should be reviewed and updated regularly as new threats emerge and security measures are enhanced.