Skip to main content

Security Reference

For the security policy, vulnerability reporting, and security model overview, see SECURITY.md in the project root.
This document contains operational details that supplement the root security policy: deployment hardening procedures, formal verification reproduction instructions, and the upstream audit trail.

Deployment Hardening (Docker)

docker-compose.yml

Key points:
  • Never bind to 0.0.0.0 — the gateway enforces loopback-only and refuses to start without auth on non-loopback
  • Non-root user — the container runs as a dedicated UID, not root
  • Read-only mounts where possible (SSH keys use :ro)
  • Memory limits prevent a runaway process from killing the host

Dockerfile

The multi-stage build enforces:
  • --frozen-lockfile on dependency install (no drift from lockfile)
  • Dev dependencies pruned in a separate stage
  • Pinned binary versions (Bun, gog CLI) — no latest tags
  • USER node in the runtime stage
  • Build failures are not silenced (pnpm build, not pnpm build || true)

Network Security

Firewall (UFW + iptables)

Required rules:
  • SSH (22): Open, but password auth disabled (pubkey only)
  • HTTP/HTTPS (80/443): Restrict to your reverse proxy or CDN IP ranges (e.g., Cloudflare)
  • All other ports: Deny by default

Docker port protection

Docker bypasses UFW by default via the DOCKER-USER iptables chain. Any service bound to 0.0.0.0 inside Docker is reachable from the internet regardless of UFW rules. Protect Docker-published ports by adding DOCKER-USER rules:
Persist with a systemd service:

SSH hardening

In /etc/ssh/sshd_config:
Install fail2ban for brute-force protection:

Data at Rest Encryption

Session transcripts are stored as plaintext JSONL in state/sessions/. File permissions (0o600) restrict access, but disk-level access would expose contents. Recommended: Encrypt the state directory with gocryptfs.
Add a systemd unit to auto-mount on boot using a keyfile. The app requires no code changes — it writes plaintext and gocryptfs handles encryption transparently. Full-disk LUKS is an alternative but requires passphrase entry on every reboot (via Dropbear SSH in initrd), which is impractical for unattended VPS operation.

Monitoring

  • Health check: curl -sf http://localhost:<HOST_PORT>/health
  • Prometheus metrics: Available at /metrics (loopback only, no auth)
  • Fail2ban: Monitor SSH brute-force attempts
  • Memory audit cron: Periodic AI scan of persistent memory for injection attempts
  • Docker logs: docker compose logs -f

Deployment Checklist

  1. SSH: Disable password auth, disable root login, enable pubkey only
  2. Install and enable fail2ban
  3. Configure UFW: allow 22, restrict 80/443 to CDN IPs, deny all else
  4. Add DOCKER-USER iptables rules for any Docker-published ports
  5. Persist iptables rules via systemd service
  6. Set .env permissions to 0600
  7. Set state/ and workspace/ ownership to match container UID/GID
  8. Set container-ssh/ permissions to 0700
  9. Build image: docker build -t crocbot:vps-prod source/
  10. Verify docker-compose.yml binds to 127.0.0.1, not 0.0.0.0
  11. Start: docker compose up -d
  12. Verify health: curl -sf http://localhost:<HOST_PORT>/health
  13. Verify Telegram webhook is receiving messages
  14. (Optional) Set up gocryptfs for state directory encryption
  15. (Optional) Set up reverse proxy (Caddy/Traefik) for HTTPS termination

Formal Verification

Machine-checked TLA+/TLC security models provide an executable, attacker-driven regression suite for the highest-risk paths. Important caveats:
  • These are models, not the full TypeScript implementation. Drift between model and code is possible.
  • Results are bounded by the state space explored by TLC; “green” does not imply security beyond the modeled assumptions and bounds.
  • Some claims rely on explicit environmental assumptions (e.g., correct deployment, correct configuration inputs).

Reproducing Results

Gateway Exposure and Open Gateway Misconfiguration

Claim: Binding beyond loopback without auth can make remote compromise possible; token/password blocks unauth attackers (per the model assumptions).
  • Green runs: make gateway-exposure-v2, make gateway-exposure-v2-protected
  • Red (expected): make gateway-exposure-v2-negative

Nodes.run Pipeline (Highest-Risk Capability)

Claim: nodes.run requires (a) node command allowlist plus declared commands and (b) live approval when configured; approvals are tokenized to prevent replay (in the model).
  • Green runs: make nodes-pipeline, make approvals-token
  • Red (expected): make nodes-pipeline-negative, make approvals-token-negative

Ingress Gating (Mentions + Control-Command Bypass)

Claim: In group contexts requiring mention, an unauthorized “control command” cannot bypass mention gating.
  • Green: make ingress-gating
  • Red (expected): make ingress-gating-negative

Routing/Session-Key Isolation

Claim: DMs from distinct peers do not collapse into the same session unless explicitly linked/configured.
  • Green: make routing-isolation
  • Red (expected): make routing-isolation-negative

Roadmap

Next models to deepen fidelity:
  • Provider-specific ingress preflight modeling
  • Routing identity-links + dmScope variants + binding precedence
  • Gateway auth conformance (proxy/tailscale specifics)

Upstream Audit Trail

Scope: Issues inherited from openclaw/openclaw that were tracked and remediated in the crocbot fork. Last updated: 2026-02-08

Resolved Issues

Remaining Open Items


External References

CVE and Advisory

Industry Analysis

Audits and Research

Prompt Injection and LLM Security