Security
Reporting a Vulnerability
Do not open a public GitHub issue. Create a private security advisory on GitHub or email the maintainers.
Disclaimer
AI agents are inherently susceptible to prompt injection, indirect prompt injection, social engineering, and jailbreaking. No security control fully prevents a sufficiently sophisticated attack. By using Clawforce you accept full responsibility for any actions the agent takes on your behalf.
Agent Isolation (Docker Pool)
The default pool backend runs each agent in its own Docker container. This is the recommended mode for any non-development deployment.
What the container enforces by default (permissive level):
cap_drop=ALL— all Linux capabilities droppedno-new-privileges— prevents privilege escalation- Memory and CPU limits (
AGENT_DOCKER_MEM_LIMIT,AGENT_DOCKER_CPU_QUOTA) - No port mapping — workers connect out to the control plane via WebSocket only
Stricter isolation (sandboxed level, UI: Safe):
Set security.docker.level = sandboxed in the agent config to enable:
- Read-only root filesystem
tmpfsfor/tmpnetwork_mode=none(no outbound network)pids_limit=256
Full system access (privileged level, UI: Power):
Set security.docker.level = privileged to remove capability restrictions. The agent can run sudo and apt-get install for system packages. Use only in trusted environments — this preset has no cap_drop or no-new-privileges.
Configure per agent via the dashboard (Settings → Security) or the API.
Volume Isolation
Each worker container is bind-mounted with only its own data directory:
{ADMIN_STORAGE_ROOT}/agents/{agent_id}/ → /agent (inside container)The worker never sees admin/, other agents' directories, or any host path outside its own directory.
Process Pool (Development Only)
When ADMIN_RUNTIME_BACKEND=process, agents run as host subprocesses. There is no OS-level isolation — only app-level guards (see Tool Security below). Use this for local development only.
Secret Management
How secrets are stored
Agent API keys and tokens live in .config/agent.json inside the agent's directory. This file is:
- Hidden from the agent itself —
AgentFSblocks read/write access to.config/,.sessions/, and.logs/ - Never returned by the config API —
clawlib.config.helpers.redact()masksapi_key,agent_token,password, and other secret fields before any GET response - Not overwritten by config PUT — redacted placeholders are stripped server-side so round-trips never erase real secrets
Production recommendations
- Set
chmod 600on{ADMIN_STORAGE_ROOT}/agents/*/\.config/agent.json - Set
chmod 700on the storage root directory - Set
ADMIN_JWT_SECRETto a strong random value (required whenCLAWFORCE_ENV=production) - Rotate agent tokens with
clawforce agent token <id> --regenerateif compromise is suspected - Restrict
CORS_ORIGINSto the exact admin UI origin in production
Authentication & Authorization
- Admin users — passwords are bcrypt-hashed; never returned by any API
- JWT tokens — used for dashboard/API auth;
ADMIN_JWT_SECRETis required in production - Login rate limiting — 5 requests/minute per IP
- RBAC — agents have an optional
owner_user_id; only the owner or asuperadmincan access settings, start/stop, or delete an agent - User management — no HTTP API exposes user listing or creation; CLI-only (
clawforce user create,clawforce user update,clawforce user list,clawforce user reset)
Tool Security (App-Level)
These controls apply in both Docker and process modes. In Docker mode they are a second layer; in process mode they are the primary defense.
Shell (exec)
Three layers of protection run in order:
| Layer | What it blocks |
|---|---|
ShellCommandPolicy | Shell injection: $(), backticks, |, &&, ||, ;, redirects |
| Deny patterns | Destructive commands: rm -rf, dd, mkfs, shutdown, env, printenv |
| Workspace restriction | Absolute paths outside the workspace, system directories (/etc, /var) |
Filesystem (read_file, write_file, edit_file, list_dir)
AgentFS validates every path before any file operation:
- Blocks
..traversal and absolute paths - Resolves symlinks and validates the target
workspace/— read/write;profiles/— read-only.config/,.sessions/,.logs/— inaccessible to the agent
Network (web_fetch)
NetworkSecurityPolicy provides SSRF protection:
- Blocks all RFC 1918 ranges, localhost, and link-local addresses
- Resolves the hostname and re-checks the IP after DNS (DNS rebinding protection)
- HTTP(S) only —
file://,ftp://are rejected - Optional domain allowlist per agent
MCP Servers
- stdio-based (
command:) — run as child processes; isolated by the container in Docker mode - HTTP-based (
url:) — connect from the worker process; can make unrestricted outbound connections — use only with trusted servers
Channel Access Control
Each channel supports an allowFrom list. An empty list allows all users (suitable for personal use). Set explicit IDs for production:
channels:
telegram:
allowFrom: ["123456789"]
slack:
allowFrom: ["U012AB3CD"]Audit Logging
Security events are emitted to the clawforce.audit logger:
| Event | Fields |
|---|---|
auth_event | event, user_id, ip, success, detail, timestamp |
vault_access | agent_id, ip, success, detail, timestamp |
Configure your log aggregator to capture this logger for security monitoring.
Known Limitations
- API keys in config are stored in plain text (no keyring by default)
- No automatic JWT session expiry
- Shell filtering blocks common patterns but is not exhaustive
- Agent tokens are stored in the database; rotate if compromised
Production Checklist
- [ ]
CLAWFORCE_ENV=productionandADMIN_JWT_SECRETset - [ ] Storage root and config files have restricted permissions (
700/600) - [ ]
CORS_ORIGINSlocked to the admin UI origin - [ ]
allowFromconfigured for all active channels - [ ] Running as a non-root user or inside a container
- [ ] Dependencies up to date (
pip-audit,npm audit) - [ ]
clawforce.auditlogger captured and monitored - [ ] Agent tokens rotated after any suspected exposure
For the latest security advisories: GitHub Security Advisories
