# Security Guide Security architecture and hardening measures for both systems. ## Overview Both the Orchestrator and Agentic Team implement defense-in-depth security: | Layer | Implementation | |-------|---------------| | Input validation | `InputValidator` — length limits, dangerous pattern detection | | Rate limiting | `TokenBucketRateLimiter` — configurable per-key rate limits | | Secret management | `SecretManager` — env-based loading, masked logging | | Audit logging | `AuditLogger` — append-only logs with 0600 permissions | | Path traversal | `/api/files/` endpoint validates paths against workspace root | | Session isolation | Per-client session state with thread-safe locking | | CORS | Configurable via `CORS_ALLOWED_ORIGINS` environment variable | | Secret keys | Generated with `os.urandom(32)` — never hardcoded | | File permissions | Session files and audit logs created with `0o600` | | Subprocess safety | `shlex.quote()` for shell arguments; no `shell=True` | ## Input Validation The `InputValidator` class (in `orchestrator/security_module/security.py`) validates: ```python from orchestrator.security_module import InputValidator # Task validation — checks length and dangerous patterns task = InputValidator.validate_task("Build a REST API") # Workflow name — alphanumeric + hyphens/underscores only name = InputValidator.validate_workflow_name("my-workflow") # File path — prevents traversal attacks path = InputValidator.validate_file_path( "src/main.py", allowed_root=Path("./workspace"), ) ``` ### Dangerous Patterns Blocked - `rm -rf` - `curl ... | bash` - `wget ... | sh` - `> /dev/` (device writes) - `format C:` (Windows) - `del /F` (Windows) ### Length Limits | Field | Max Length | |-------|-----------| | Task description | 50,000 chars | | Workflow name | 100 chars | | Agent name | 50 chars | | File path | 4,096 chars | | Client ID | 128 chars | ## Rate Limiting ```python from orchestrator.security_module import TokenBucketRateLimiter limiter = TokenBucketRateLimiter(rate=60, window=60) # 60 req/min limiter.check_limit("user_123") # Raises RateLimitError if exceeded ``` ## Environment Variables | Variable | Purpose | |----------|---------| | `FLASK_SECRET_KEY` | Orchestrator Flask session key | | `FLASK_SECRET_KEY_AGENTIC` | Agentic Team Flask session key | | `CORS_ALLOWED_ORIGINS` | Comma-separated allowed origins | | `FLASK_DEBUG` | Set to `true` only in development | ## Production Checklist - [ ] Set `FLASK_SECRET_KEY` and `FLASK_SECRET_KEY_AGENTIC` to strong random values - [ ] Set `CORS_ALLOWED_ORIGINS` to your specific domains - [ ] Set `FLASK_DEBUG=false` - [ ] Enable rate limiting in config - [ ] Review audit logs regularly (`logs/audit.log`) - [ ] Run with non-root user (Dockerfile uses UID 1000) - [ ] Use TLS termination at load balancer/ingress level ## Defense-in-Depth Security Layers The following diagram illustrates how every incoming request passes through multiple security layers before reaching the execution engine. Each layer independently validates and can reject the request. ```mermaid flowchart TD REQ["Incoming Request
(REST API / WebSocket / CLI)"] --> CORS subgraph layer1["Layer 1: Transport Security"] CORS["CORS Policy
CORS_ALLOWED_ORIGINS"] SESSION["Session Isolation
Per-client state + thread-safe lock"] SECRET_KEY["Flask Secret Key
os.urandom(32)"] end CORS --> IV subgraph layer2["Layer 2: Input Validation"] IV["InputValidator"] IV_TASK["Task length check
(max 50,000 chars)"] IV_PATTERN["Dangerous pattern scan
(rm -rf, curl|bash, etc.)"] IV_NAME["Name format check
[a-zA-Z0-9_-]"] IV_PATH["Path traversal prevention
resolve against workspace root"] IV --> IV_TASK --> IV_PATTERN --> IV_NAME --> IV_PATH end IV_PATH --> RL subgraph layer3["Layer 3: Rate Limiting"] RL["TokenBucketRateLimiter
Per-key: 60 req / 60s window"] end RL --> SM subgraph layer4["Layer 4: Secret Masking"] SM["SecretManager
Load API_KEY_*, SECRET_*,
TOKEN_*, PASSWORD_*"] SM_MASK["Mask secrets in all
log output and responses"] SM --> SM_MASK end SM_MASK --> AL subgraph layer5["Layer 5: Audit Logging"] AL["AuditLogger
JSON-line events to logs/audit.log"] AL_PERM["File permissions: 0o600
Append-only"] AL --> AL_PERM end AL_PERM --> EXEC subgraph layer6["Layer 6: Subprocess Safety"] EXEC["Agent Execution"] SHLEX["shlex.quote() all arguments"] NO_SHELL["No shell=True"] EXEC --> SHLEX EXEC --> NO_SHELL end IV_TASK -->|"length exceeded"| R400["400 Bad Request"] IV_PATTERN -->|"dangerous pattern"| R400 IV_NAME -->|"invalid format"| R400 IV_PATH -->|"traversal detected"| R403["403 Forbidden"] RL -->|"rate exceeded"| R429["429 Too Many Requests"] style layer1 fill:#3498db20,stroke:#3498db style layer2 fill:#e74c3c20,stroke:#e74c3c style layer3 fill:#e67e2220,stroke:#e67e22 style layer4 fill:#8e44ad20,stroke:#8e44ad style layer5 fill:#27ae6020,stroke:#27ae60 style layer6 fill:#2c3e5020,stroke:#2c3e50 style R400 fill:#e74c3c,color:#fff style R403 fill:#e74c3c,color:#fff style R429 fill:#e74c3c,color:#fff ```