This skill should be used when the user asks to "isolate OpenClaw in Docker", "containerize the agent", "set up network isolation", "sandbox OpenClaw", "restrict container egress", or mentions Docker security, container isolation, network policies, or agent sandboxing. Implements Docker container security, network isolation, resource limits, and filesystem restrictions for OpenClaw and Claude Code deployments. Use this skill whenever container-level isolation needs to be implemented, even if they don't explicitly ask for "openclaw-isolation". [EXPLICIT]
From jm-adknpx claudepluginhub javimontano/jm-adk-alfaThis skill is limited to using the following tools:
agents/guardian.mdagents/lead.mdagents/specialist.mdagents/support.mdevals/evals.jsonknowledge/body-of-knowledge.mdknowledge/knowledge-graph.mdprompts/meta.mdprompts/primary.mdprompts/variations/deep.mdprompts/variations/quick.mdreferences/docker-patterns.mdtemplates/output.docx.mdtemplates/output.htmlContainer isolation is defense-in-depth for OpenClaw deployments. Even when the agent engine is trusted, the tools it invokes (Bash, file system, browser, APIs) operate on the host. A compromised or misbehaving tool call without container isolation has unrestricted access to the host filesystem, network, and processes. This skill produces hardened Docker configurations, network policies, and resource limits that constrain the blast radius of any single tool invocation to the container boundary. [EXPLICIT]
El contenedor no es la defensa — es la jaula de contención. Docker no previene ataques; limita el daño. La verdadera seguridad es capas: contenedor + red + filesystem + límites de recursos, cada uno independiente del otro.
Use this skill when:
Trigger phrases: "isolate OpenClaw", "containerize the agent", "Docker security for Claude Code", "sandbox the agent", "restrict container egress", "set up network policies for OpenClaw", "agent container hardening" [EXPLICIT]
| Need | Use Instead | Why |
|---|---|---|
| Designing security architecture (not implementing) | 5022-open-claude-security | Architecture design, not container implementation |
| General app security architecture | 5019-security-architecture | System-level, not container-level |
| Building OpenClaw from scratch | 9081-open-claw-builder | Builds agents; this skill isolates them |
| Tool-level authorization controls | 5024-openclaw-tool-auth | Per-tool auth, not container isolation |
| Full personal deployment | 5025-openclaw-personal-deploy | End-to-end deploy; this skill handles isolation only |
| Kubernetes orchestration | Out of scope | This skill covers Docker, not K8s |
Parse $ARGUMENTS: $1 = project name, $2 = deployment mode. [EXPLICIT]
Deployment modes:
--personal: Single-user, local Docker. Tighter limits, simpler network. [EXPLICIT]--team: Multi-container shared environment. Adds inter-container policies and shared volumes. [EXPLICIT]--personal [EXPLICIT]Parameters:
{MODO}: piloto-auto (default) | desatendido | supervisado | paso-a-paso [EXPLICIT]
{FORMATO}: markdown (default) | yaml | dualDetect existing Docker and project context:
Glob Dockerfile docker-compose*.yml .dockerignore
Glob .claude/settings.json .claude/settings.local.json .mcp.json CLAUDE.md
Glob **/Dockerfile **/docker-compose*.yml
Bash(docker --version 2>/dev/null || echo "Docker not installed")
Bash(docker compose version 2>/dev/null || echo "Docker Compose not available")
Load reference materials:
Read ${CLAUDE_SKILL_DIR}/references/docker-patterns.md
Cross-reference with security architecture if available:
Glob skills/**/5022-open-claude-security/SKILL.md
Decision tree:
Build a multi-stage, minimal, non-root Dockerfile for the OpenClaw agent. [EXPLICIT]
Requirements:
builder) installs dependencies and compiles. Stage 2 (runtime) copies only the built artifacts. This eliminates build tools, package managers, and source code from the final image. [EXPLICIT]node:22-alpine or debian:bookworm-slim depending on project requirements. Never use node:latest or ubuntu:latest — these include hundreds of unnecessary packages that expand attack surface. [EXPLICIT]openclaw user (UID 1001) and group. Set USER openclaw before the CMD instruction. The agent process must never run as root inside the container. [EXPLICIT]COPY .env . or ARG SECRET_KEY=.... Secrets enter via Docker secrets, mounted files, or environment variables at runtime only. Every layer is inspectable via docker history. [EXPLICIT]node:22-alpine@sha256:abc...) and all package versions (npm ci --ignore-scripts). Reproducible builds prevent supply chain drift. [EXPLICIT]rm -rf /var/cache/apk/*), disable shell access where possible, and set WORKDIR /app with restricted permissions. [EXPLICIT]HEALTHCHECK --interval=30s --timeout=5s CMD curl -f http://localhost:${PORT}/health || exit 1 to enable orchestrator-level liveness detection. [INFERRED]Template Dockerfile:
# === Stage 1: Builder ===
FROM node:22-alpine@sha256:<pinned-digest> AS builder
WORKDIR /build
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts --production=false
COPY . .
RUN npm run build && npm prune --production
# === Stage 2: Runtime ===
FROM node:22-alpine@sha256:<pinned-digest> AS runtime
RUN addgroup -g 1001 openclaw && adduser -u 1001 -G openclaw -s /bin/false -D openclaw
RUN rm -rf /var/cache/apk/* /tmp/* /root/.npm
WORKDIR /app
COPY --from=builder --chown=openclaw:openclaw /build/dist ./dist
COPY --from=builder --chown=openclaw:openclaw /build/node_modules ./node_modules
COPY --from=builder --chown=openclaw:openclaw /build/package.json ./
USER openclaw
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
Validation checks for S1:
RUN apt-get install in runtime stage [EXPLICIT]USER directive present and not root [EXPLICIT]COPY .env, ARG PASSWORD, or secret-bearing instructions [EXPLICIT]Produce a hardened docker-compose.yml with security options, capability restrictions, and resource limits. [EXPLICIT]
Security options applied:
security_opt: [no-new-privileges:true] — Prevents the container process from gaining additional privileges via setuid/setgid binaries. This blocks a common container escape vector. [EXPLICIT]cap_drop: [ALL] — Drops all Linux capabilities. The agent does not need NET_RAW, SYS_ADMIN, MKNOD, or any other capability. If a specific capability is genuinely needed, add it back with cap_add and document the justification. [EXPLICIT]read_only: true — Sets the root filesystem to read-only. Combined with targeted tmpfs mounts, this prevents the agent from writing to unexpected paths. [EXPLICIT]tmpfs mounts — Writable temporary storage for /tmp and /app/workspace with size limits. The agent can write to these paths but nowhere else. [EXPLICIT]mem_limit and cpus — Hard resource ceilings. Personal deployments: 1GB RAM, 1 CPU. Team deployments: 2GB RAM, 2 CPUs. These prevent runaway processes from starving the host. [EXPLICIT]pids_limit — Restricts the number of processes the container can spawn. Prevents fork bombs. Default: 100. [EXPLICIT]restart: unless-stopped — Ensures the container recovers from crashes but does not restart if explicitly stopped. [INFERRED]Resource limit guidelines:
| Deployment | Memory | CPU | PIDs | tmpfs /tmp | tmpfs /app/workspace |
|---|---|---|---|---|---|
--personal | 1024m | 1.0 | 100 | 64m | 256m |
--team | 2048m | 2.0 | 200 | 128m | 512m |
[EXPLICIT]
Template docker-compose.yml (personal mode):
version: "3.9"
services:
openclaw-agent:
build:
context: .
dockerfile: Dockerfile
container_name: openclaw-agent
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp:size=64m,noexec,nosuid
- /app/workspace:size=256m,noexec,nosuid
mem_limit: 1024m
mem_reservation: 256m
cpus: "1.0"
pids_limit: 100
networks:
- openclaw-internal
env_file:
- .env
ports:
- "127.0.0.1:3000:3000"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
timeout: 5s
retries: 3
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
networks:
openclaw-internal:
driver: bridge
internal: true
Validation checks for S2:
no-new-privileges set to true [EXPLICIT]Implement network policies that restrict container egress to only approved destinations. [EXPLICIT]
Principles:
internal: true network driver to block all external traffic by default. [EXPLICIT]network_mode: host. This eliminates all network isolation. [EXPLICIT]127.0.0.1 only, not 0.0.0.0. This prevents external access to the agent's HTTP interface. [EXPLICIT]Egress allowlist implementation with iptables (host-level):
#!/bin/bash
# egress-allowlist.sh — Restrict container egress to approved IPs
# Run on the Docker host, not inside the container
CONTAINER_SUBNET="172.20.0.0/16"
ALLOWED_IPS=(
"104.18.0.0/16" # Anthropic API (api.anthropic.com)
"140.82.112.0/20" # GitHub API
)
# Default deny all egress from container subnet
iptables -I FORWARD -s $CONTAINER_SUBNET -j DROP
# Allow established connections (responses to allowed requests)
iptables -I FORWARD -s $CONTAINER_SUBNET -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow specific destinations
for ip in "${ALLOWED_IPS[@]}"; do
iptables -I FORWARD -s $CONTAINER_SUBNET -d $ip -j ACCEPT
done
# Allow DNS resolution (to host DNS only)
iptables -I FORWARD -s $CONTAINER_SUBNET -d 172.20.0.1 -p udp --dport 53 -j ACCEPT
Network architecture (personal mode):
┌─────────────────────────────────────────────┐
│ Docker Host │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ openclaw-internal (bridge, internal) │ │
│ │ │ │
│ │ ┌──────────────┐ ┌─────────────┐ │ │
│ │ │ openclaw- │ │ egress- │ │ │
│ │ │ agent │──│ proxy │ │ │
│ │ │ (no egress) │ │ (allowlist) │ │ │
│ │ └──────────────┘ └──────┬──────┘ │ │
│ │ │ │ │
│ └───────────────────────────┼──────────┘ │
│ │ │
│ ┌───────────────────────────┼──────────┐ │
│ │ openclaw-egress (bridge) │ │ │
│ │ ▼ │ │
│ │ [Allowlisted IPs] │ │
│ └──────────────────────────────────────┘ │
│ │ │
└──────────────────────────────┼───────────────┘
▼
Internet (filtered)
Validation checks for S3:
network_mode: host anywhere in compose [EXPLICIT]internal: true [EXPLICIT]127.0.0.1, not 0.0.0.0 [EXPLICIT]Configure bind mounts, volume permissions, and path blocking to enforce least-privilege filesystem access. [EXPLICIT]
Principles:
read_only: true in compose. The container root is immutable at runtime. [EXPLICIT]tmpfs for /tmp (ephemeral scratch) and /app/workspace (agent work area). Both have size limits and noexec,nosuid flags. [EXPLICIT]:ro). Never mount /, /etc, /var/run/docker.sock, or the user's home directory. [EXPLICIT]/var/run/docker.sock inside the container grants full Docker API access — equivalent to root on the host. This is categorically forbidden. [EXPLICIT]/var/run/docker.sock — Docker daemon control/etc/shadow, /etc/passwd — Host credential files~/.ssh/ — SSH private keys~/.aws/, ~/.gcloud/ — Cloud provider credentials~/.gnupg/ — GPG private keys/proc, /sys — Kernel interfaces (beyond default Docker masking)Volume configuration template:
services:
openclaw-agent:
volumes:
# Project source — read-only
- ./project:/app/project:ro
# Agent output — writable, host-accessible
- ./output:/app/output:rw
tmpfs:
- /tmp:size=64m,noexec,nosuid,nodev
- /app/workspace:size=256m,noexec,nosuid,nodev
read_only: true
Validation checks for S4:
.ssh, .aws, .gnupg) [EXPLICIT]:ro [EXPLICIT]tmpfs mounts have size limits and noexec [EXPLICIT]no-new-privileges, pids_limit, read_only) require Docker Engine 24.0+. Older versions may silently ignore these options. [EXPLICIT]iptables-persistent or equivalent. [INFERRED]5006-secrets-management for vault integration. [EXPLICIT]If Docker is not installed or cannot be installed (embedded systems, restricted environments), provide alternative isolation using:
ProtectSystem=strict, ProtectHome=yes, PrivateTmp=yes, NoNewPrivileges=yes in a systemd service unit. [EXPLICIT]Docker Desktop for Windows runs containers inside a WSL2 Linux VM. Key differences:
/mnt/c/...) is significantly degraded. Mount from the Linux filesystem (~/project) instead. [EXPLICIT]docker group inside WSL2. [INFERRED].wslconfig. [EXPLICIT]Rootless Docker runs the Docker daemon and containers without root privileges. Implications:
iptables rules require slirp4netns or pasta for network isolation instead of kernel-level iptables. Egress filtering is more limited. [EXPLICIT]# DO NOT USE — Every line is a security gap
version: "3.9"
services:
agent:
image: node:latest # Unpinned, bloated image
network_mode: host # No network isolation
privileged: true # Full host access
volumes:
- /:/host # Entire host filesystem
- /var/run/docker.sock:/var/run/docker.sock # Docker API
environment:
- API_KEY=sk-ant-xxxxx # Secret in compose file
ports:
- "3000:3000" # Bound to 0.0.0.0
Issues: [EXPLICIT]
node:latest — unpinned, includes build tools, 900MB+network_mode: host — zero network isolationprivileged: true — equivalent to running on host as root/:/host — entire host filesystem exposeddocker inspectversion: "3.9"
services:
openclaw-agent:
build:
context: .
dockerfile: Dockerfile
container_name: openclaw-agent
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp:size=64m,noexec,nosuid,nodev
- /app/workspace:size=256m,noexec,nosuid,nodev
mem_limit: 1024m
mem_reservation: 256m
cpus: "1.0"
pids_limit: 100
volumes:
- ./project:/app/project:ro
- ./output:/app/output:rw
networks:
- openclaw-internal
env_file:
- .env
ports: ["127.0.0.1:3000:3000"]
restart: unless-stopped
networks:
openclaw-internal:
driver: bridge
internal: true
Why secure: cap_drop ALL, read-only root, sized tmpfs, resource limits, internal network, localhost-only port, env-file secrets. [EXPLICIT]
Before delivering the isolation configuration, verify:
security_opt, cap_drop: ALL, read_only, resource limits [EXPLICIT]internal: true and ports bound to 127.0.0.1 [EXPLICIT].ssh, .aws, .gnupg) [EXPLICIT]mem_limit, cpus, pids_limit all defined with justified values [EXPLICIT]noexec,nosuid,nodev flags and size limits [EXPLICIT]| File | Content | Load When |
|---|---|---|
references/docker-patterns.md | Dockerfile best practices, compose security, network drivers, seccomp, AppArmor | Always [EXPLICIT] |
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.