Security Philosophy
IronClaw implements a zero-trust, defense-in-depth security architecture. Every component is treated as potentially compromised, with multiple overlapping layers of protection.Threat Model
IronClaw operates across four trust boundaries:| Boundary | Trust Level | Protection |
|---|---|---|
| Local user | Fully trusted | TUI, web gateway (loopback), CLI commands |
| Browser client | Authenticated | Bearer token, CORS, Origin validation, CSRF protection |
| Docker containers | Untrusted (sandboxed) | Per-job tokens, allowlisted egress, dropped capabilities |
| External services | Untrusted | Shared secret authentication for webhooks |
Key Assumptions
- The local machine is single-user
- Docker containers are adversarial
- Webhook senders must prove knowledge of shared secret
- MCP server URLs are operator-configured (trusted destinations)
- LLM output may contain prompt injection attempts
WASM Sandbox
All untrusted tools run in isolated WebAssembly containers with strict capability-based permissions.Isolation Model
Source:
src/tools/wasm/, src/sandbox/Capability-Based Permissions
Tools must explicitly declare capabilities in<tool>.capabilities.json:
HTTP Access
HTTP Access
- Host allowlist (exact or wildcard matching)
- Path prefix restrictions
- HTTP method filtering
- HTTPS requirement
- Userinfo in URLs rejected (prevents
user:pass@hostbypass) - Path traversal blocked (
../,%2e%2e/)
Secrets Access
Secrets Access
- Explicit secret name allowlist
- Secrets injected at host boundary
- WASM code never sees actual values
- Leak detection on all requests/responses
Tool Invocation
Tool Invocation
- Explicit tool name allowlist
- Prevents tool-to-tool privilege escalation
- Circular invocation prevention
Endpoint Allowlisting
Source:
src/tools/wasm/allowlist.rs- Host Matching: Exact domain or wildcard pattern (
*.example.com) - Path Prefix: Request path must start with allowed prefix
- Method Restriction: Only declared HTTP methods permitted
- Scheme Validation: HTTPS required by default
- URL Normalization: Percent-encoding validation, path traversal detection
Resource Limits
WASM tools are subject to runtime constraints:- Memory: Configurable limit (default varies by tool)
- CPU: Execution time limits
- Network: Rate limiting per tool
- Disk: No filesystem access (in-memory only)
Credential Protection
Secrets are never exposed to untrusted code. IronClaw uses credential injection at the host boundary.Secret Storage
Source:
src/secrets/- All secrets encrypted with AES-256-GCM
- Encryption keys stored in system keychain (OS-specific)
- Per-user secret namespaces
- Metadata tracked in database (name, created, updated)
- Actual values never logged or persisted unencrypted
Credential Injection
Source:
src/tools/wasm/credential_injector.rs, src/sandbox/proxy/http.rsAuthorization: Bearer {token}headerAuthorization: Basic {base64}header- Custom headers (e.g.,
X-API-Key: {secret}) - Query parameters (e.g.,
?api_key={secret})
- Tool must declare allowed secrets
- Secrets resolved at request time from encrypted store
- Leak detection scans request before sending
- Leak detection scans response before returning to tool
Leak Detection
Source:
src/safety/leak_detector.rs- Request Scan: Before sending outbound requests
- Response Scan: Before returning responses to WASM
- Multi-Pattern Matching: Aho-Corasick algorithm for efficiency
- Secret Patterns: Exact match and regex-based detection
- Block the request/response
- Log security event
- Return error to caller
- Optional notification to operator
Prompt Injection Defense
External content (tool outputs, webhook payloads, user messages from untrusted sources) passes through multiple security layers.Source:
src/safety/Detection Layers
Pattern Detection
Regex-based detection of common injection patterns:
- Role manipulation (
System:,Assistant:,You are now) - Instruction override (
Ignore previous,Disregard all) - Data exfiltration attempts (
Send to,POST to) - Jailbreak phrases (
DAN mode,Developer override)
Content Sanitization
Escape or remove dangerous content:
- Strip control characters
- Escape backticks and code blocks
- Normalize whitespace
- Remove embedded instructions
Policy Enforcement
Apply severity-based actions:
- Block: Reject content entirely
- Warn: Log warning, allow with caution flag
- Review: Flag for human review
- Sanitize: Clean content automatically
Safety Policies
Policies are defined in the configuration:Safety Policy Example
Docker Container Security
Sandbox containers run with defense-in-depth hardening:Source:
src/sandbox/container.rs, src/NETWORK_SECURITY.mdContainer Configuration
Capabilities
Drop ALL capabilities, add only CHOWN. Prevents privilege escalation, raw sockets, kernel module loading, etc.
User Isolation
Run as non-root (UID 1000:1000). Combined with read-only filesystem, limits attack surface.
Read-Only Filesystem
Root filesystem is read-only (except tmpfs mounts). Prevents persistence of malicious code.
Network Isolation
Bridge mode with HTTP proxy. All egress traffic routed through allowlist-enforced proxy.
Security Options
Container Security Settings
HTTP Proxy for Egress
Source:
src/sandbox/proxy/http.rs- Binds to 127.0.0.1 only (not accessible from network)
- Domain allowlist enforcement
- Empty allowlist = deny all (fail-closed)
- HTTPS tunneling (CONNECT) with 30-minute timeout
- Credential injection for HTTP (not HTTPS - by design)
- Hop-by-hop header filtering
- LLM provider endpoints (NEAR AI, OpenAI, Anthropic, etc.)
- Package registries (PyPI, npm, crates.io)
- Version control (GitHub, GitLab)
- Configurable via
SANDBOX_EXTRA_DOMAINS
Timeout and Cleanup
Containers are subject to strict lifecycle management:- Execution Timeout: Configurable per job (default 600s)
- Forced Stop: Container stopped after timeout
- Auto-Remove: Container automatically deleted after execution
- Output Limits: Stdout/stderr capped to prevent log bombs
- Token Revocation: Per-job bearer token revoked on cleanup
Network Security
IronClaw has multiple network-facing surfaces with layered authentication.Source:
src/NETWORK_SECURITY.md (full inventory)Web Gateway
Bind Address:127.0.0.1:3000 (default, loopback only)
Authentication:
- Bearer token in
Authorizationheader - Query parameter
?token=for SSE (constant-time comparison) - Random hex token generated if not configured
- CORS allowlist (two origins: bind IP and localhost)
- WebSocket Origin validation
- Rate limiting (30 req/60s for chat endpoint)
- Body limit (1 MB max)
- Security headers (
X-Content-Type-Options: nosniff,X-Frame-Options: DENY)
HTTP Webhook Server
Bind Address:0.0.0.0:8080 (default, all interfaces)
Authentication:
- Shared secret in JSON body (
secretfield) - Constant-time comparison via
subtle::ConstantTimeEq - Required to start server (fail if not configured)
- Content-Type validation (
application/jsononly) - Rate limiting (60 req/min)
- Body limit (64 KB max)
- Message content limit (32 KB max)
- CSRF protection (secret in body, not cookie/header)
Orchestrator Internal API
Bind Address:127.0.0.1:50051 (macOS/Windows), 0.0.0.0:50051 (Linux)
Authentication:
- Per-job bearer token (32 bytes, hex-encoded)
- Constant-time comparison
- Job ID extracted from URL path
- Token scoped to specific job (cannot access other jobs)
- Ephemeral tokens (in-memory only, never persisted)
- Token revocation on container cleanup
- Credential grants scoped to specific secrets
- No rate limiting (tokens are per-job scoped)
Built-in Tool SSRF Protections
The built-inhttp tool has comprehensive SSRF defenses:
Source:
src/tools/builtin/http.rsHTTPS Only
Rejects
http:// URLs. All requests must use TLS.Localhost Blocked
Rejects
localhost and *.localhost domains.Private IP Blocked
Blocks RFC 1918, loopback, link-local, multicast, unspecified addresses.
Cloud Metadata Blocked
Blocks
169.254.169.254 (AWS/GCP metadata endpoint).DNS Rebinding Protection
Resolves hostname and checks all IPs against blocklist.
Redirect Blocking
Returns error on 3xx responses (prevents SSRF via redirect).
- Response size limit (5 MB max)
- 30-second timeout
- Outbound leak scan (URL, headers, body)
- Requires user approval before execution
Data Protection
All data stays on your machine with strong encryption:Local Storage
All data stored in your PostgreSQL database. No cloud storage, no vendor access.
Encryption at Rest
Secrets encrypted with AES-256-GCM. Keys stored in OS keychain.
No Telemetry
Zero telemetry, analytics, or data sharing. Open source, auditable.
Audit Logs
Full audit trail of tool executions, LLM calls, job events. Queryable via database.
Security Best Practices
When deploying IronClaw:Use Strong Secrets
Generate strong, random secrets for webhook authentication and gateway tokens. Use environment variables, never hardcode.
Restrict Network Access
- Web gateway: Keep on loopback (
127.0.0.1) - Webhook server: Use firewall rules to allow only known IPs
- Orchestrator: Block port 50051 from external access on Linux
TLS Termination
Front IronClaw with a reverse proxy (nginx, Caddy) or tunnel (Cloudflare, ngrok) for TLS.
Review Tool Capabilities
Audit WASM tool capabilities before loading. Verify allowlists and secret access.
Monitor Audit Logs
Regularly review job events, tool executions, and security findings in the database.
IronClaw’s defense-in-depth architecture provides strong protection, but security is a shared responsibility. Follow best practices for deployment and configuration.
