/docker-security
Opt-in advanced Docker security hardening beyond the docker-setup baseline — LAN containment with DNS policy, resource bounds with kernel-hygiene sysctls, and a boot-time plugin install audit log. Applied as a reversible docker-compose overlay (does not touch the base compose
Claude Code
$ npx -y skills add gtapps/hermitd --skill docker-security --agent claude-code
Codex
$ npx skills add gtapps/hermitd --skill docker-security -a codex -y
Cursor
$ npx skills add gtapps/hermitd --skill docker-security -a cursor -y
Gemini CLI
$ npx skills add gtapps/hermitd --skill docker-security -a gemini-cli -y
GitHub Copilot
$ npx skills add gtapps/hermitd --skill docker-security -a github-copilot -y
OpenCode
$ npx skills add gtapps/hermitd --skill docker-security -a opencode -y
Windsurf
$ npx skills add gtapps/hermitd --skill docker-security -a windsurf -y
SKILL.md
docker-security.SKILL.mdname: docker-security
description: Opt-in advanced Docker security hardening beyond the docker-setup baseline — LAN containment with DNS policy, resource bounds with kernel-hygiene sysctls, and a boot-time plugin install audit log. Applied as a reversible docker-compose overlay (does not touch the base compose file) and verified against the live container. Run after /docker-setup; requires bridge networking.
disable-model-invocation: true
Docker Security
Advanced hardening for already-deployed hermit containers. Each toggle is opt-in, presented with honest cost/benefit framing, and applied as a `docker-compose.security.yml` overlay that the `hermitd-docker` wrapper auto-detects. Reversal: re-run and answer No to every prompt, or delete `docker-compose.security.yml` directly.
**Tone:** Honest about tradeoffs. Tell operators what each toggle does AND does not protect. Do not oversell.
Each step's commands depend on the previous step's answer, so run them in order.
Templates live in `${CLAUDE_SKILL_DIR}/../../state-templates/docker/security/`.
Trust model framing (read to operator at the start of step 2)
> Installing a plugin runs that plugin's hooks and skills with the same authority as hermit. The container hardening here reduces what a *compromised* plugin can do to the host kernel and your local network — it does not vet the plugin's intent, sandbox its file access within the project, or prevent it from acting on your behalf via the agent. A malicious or careless plugin still runs as you. > > **Honest limitation:** DNS policy below blocks domain-based exfil/C2 but cannot stop direct-IP egress to a hardcoded public address.
Plan
0. Refuse to run inside the hermit container
This skill is host-only — it writes a `docker-compose.security.yml` overlay on the host and recreates the container with stronger isolation.
Run: `[ -f /.dockerenv ] || [ -f /run/.containerenv ] && echo container || echo host`
If the output is `container`, **stop immediately** — do not proceed to step 1. Print:
> This skill writes a `docker-compose.security.yml` overlay on the host and recreates the container with stronger isolation. Run it from your host shell in the project root. To inspect the live security posture *inside* the running container, run `/hermitd:hermit-doctor` — it includes a `docker-security` check.
1. Prerequisites
1. Read `.hermit/config.json`. If missing: "Run `/hermitd:hatch` first." Stop. 2. Verify `docker-compose.hermit.yml` exists at the project root. If missing: "Run `/hermitd:docker-setup` first." Stop. 3. **Docker daemon check**: run `timeout 10s docker info >/dev/null 2>&1`. If it fails or times out: tell the operator "Docker daemon is not reachable or timed out. Start Docker before re-running `/docker-security`." Stop. 4. Read `docker.network_mode` from config (default: `"bridge"`). If `"host"`, set `HOST_NETWORK_MODE=true` and surface to operator: "Detected `network_mode: host` in your config. The LAN containment toggle (Prompt 1) will be skipped — it would replace host mode and break your HA / host-bound service access. Resource bounds (Prompt 2) will not apply network sysctls in host mode either; Docker rejects them and the container would fail to start." 5. **Detect hermit ports**: run `timeout 10s docker compose -f docker-compose.hermit.yml config --format json 2>/dev/null` and parse `.services.hermit.ports`. Store as in-memory `detected_hermit_ports` (array of long-form Compose port objects: `{target, published, host_ip, protocol, mode}`). If the command fails or returns no JSON, fall back to `grep -n '^\s*ports:' docker-compose.hermit.yml` and set `detected_hermit_ports_unparsed=true` if found. Either way, a non-empty result means ports are present. 6. Check whether the container is currently running: `docker compose -f docker-compose.hermit.yml ps --status running --format '{{.Service}}' 2>/dev/null | grep -x hermit`. If absent: tell the operator "Container is not running. The wizard will still write the overlay; you'll see the live verification only after starting the container with `hermitd-docker up`." 7. Read current `docker.security.*` from config.json. Also read `sandbox.enabled` from the target settings file (same `hatch_target` routing as hatch/docker-setup: `hatch_target == "local"` → `.claude/settings.local.json`; else → `.claude/settings.json`) — display only, hermit does not configure this key. Print a "current posture" summary. Example:
Current security posture:
LAN containment: off
Resource bounds: off
Audit log: off
Baseline (always on):
cap_drop: ALL, no-new-privileges, pids_limit: 2048
Sandbox (bash tool isolation, operator-managed via /sandbox):
enabled: true (or: false / not configured)2. Trust model framing
Print the trust-model paragraph from the top of this file (the blockquote). Then continue.
3. Prompt 1 — LAN containment + DNS policy
If `HOST_NETWORK_MODE` is true, **do not present this prompt**. Tell the operator: "Skipping LAN containment — incompatible with `network_mode: host`. Run `/hermitd:docker-setup` to switch to bridge mode if you want this hardening." Continue to step 4.
Otherwise, ask with `AskUserQuestion` (header: `"LAN containment"`):
question: "Add LAN containment with DNS policy? (firewall sidecar + DNS allowlist)"
options:
- label: "Yes — recommended (LAN block + DNS log-only)"
description: "Blocks RFC1918 + cloud metadata. DNS in log-only mode: allows everything, logs blocked queries for tuning."
- label: "Yes — strict (LAN block + DNS enforce)"
description: "Same LAN block. DNS returns NXDOMAIN for any domain not on the allowlist."
- label: "No"
description: "Skip this toggle."Map: `"Yes — recommended"` → `dns_mode: "log-only"`. `"Yes — strict"` → `dns_mode: "enforce"`. `"No"` → skip to step 4.
3-pre. Port conflict handling (only if a "Yes" option was selected above)
If the operator selected a "Yes
Read more
name: docker-security description: Opt-in advanced Docker security hardening beyond the docker-setup baseline — LAN containment with DNS policy, resource bounds with kernel-hygiene sysctls, and a boot-time plugin install audit log. Applied as a reversible docker-compose overlay (does not touch the base compose file) and verified against the live container. Run after /docker-setup; requires bridge networking. disable-model-invocation: true
Docker Security
Advanced hardening for already-deployed hermit containers. Each toggle is opt-in, presented with honest cost/benefit framing, and applied as a `docker-compose.security.yml` overlay that the `hermitd-docker` wrapper auto-detects. Reversal: re-run and answer No to every prompt, or delete `docker-compose.security.yml` directly.
**Tone:** Honest about tradeoffs. Tell operators what each toggle does AND does not protect. Do not oversell.
Each step's commands depend on the previous step's answer, so run them in order.
Templates live in `${CLAUDE_SKILL_DIR}/../../state-templates/docker/security/`.
Trust model framing (read to operator at the start of step 2)
> Installing a plugin runs that plugin's hooks and skills with the same authority as hermit. The container hardening here reduces what a *compromised* plugin can do to the host kernel and your local network — it does not vet the plugin's intent, sandbox its file access within the project, or prevent it from acting on your behalf via the agent. A malicious or careless plugin still runs as you. > > **Honest limitation:** DNS policy below blocks domain-based exfil/C2 but cannot stop direct-IP egress to a hardcoded public address.
Plan
0. Refuse to run inside the hermit container
This skill is host-only — it writes a `docker-compose.security.yml` overlay on the host and recreates the container with stronger isolation.
Run: `[ -f /.dockerenv ] || [ -f /run/.containerenv ] && echo container || echo host`
If the output is `container`, **stop immediately** — do not proceed to step 1. Print:
> This skill writes a `docker-compose.security.yml` overlay on the host and recreates the container with stronger isolation. Run it from your host shell in the project root. To inspect the live security posture *inside* the running container, run `/hermitd:hermit-doctor` — it includes a `docker-security` check.
1. Prerequisites
1. Read `.hermit/config.json`. If missing: "Run `/hermitd:hatch` first." Stop. 2. Verify `docker-compose.hermit.yml` exists at the project root. If missing: "Run `/hermitd:docker-setup` first." Stop. 3. **Docker daemon check**: run `timeout 10s docker info >/dev/null 2>&1`. If it fails or times out: tell the operator "Docker daemon is not reachable or timed out. Start Docker before re-running `/docker-security`." Stop. 4. Read `docker.network_mode` from config (default: `"bridge"`). If `"host"`, set `HOST_NETWORK_MODE=true` and surface to operator: "Detected `network_mode: host` in your config. The LAN containment toggle (Prompt 1) will be skipped — it would replace host mode and break your HA / host-bound service access. Resource bounds (Prompt 2) will not apply network sysctls in host mode either; Docker rejects them and the container would fail to start." 5. **Detect hermit ports**: run `timeout 10s docker compose -f docker-compose.hermit.yml config --format json 2>/dev/null` and parse `.services.hermit.ports`. Store as in-memory `detected_hermit_ports` (array of long-form Compose port objects: `{target, published, host_ip, protocol, mode}`). If the command fails or returns no JSON, fall back to `grep -n '^\s*ports:' docker-compose.hermit.yml` and set `detected_hermit_ports_unparsed=true` if found. Either way, a non-empty result means ports are present. 6. Check whether the container is currently running: `docker compose -f docker-compose.hermit.yml ps --status running --format '{{.Service}}' 2>/dev/null | grep -x hermit`. If absent: tell the operator "Container is not running. The wizard will still write the overlay; you'll see the live verification only after starting the container with `hermitd-docker up`." 7. Read current `docker.security.*` from config.json. Also read `sandbox.enabled` from the target settings file (same `hatch_target` routing as hatch/docker-setup: `hatch_target == "local"` → `.claude/settings.local.json`; else → `.claude/settings.json`) — display only, hermit does not configure this key. Print a "current posture" summary. Example:
Current security posture:
LAN containment: off
Resource bounds: off
Audit log: off
Baseline (always on):
cap_drop: ALL, no-new-privileges, pids_limit: 2048
Sandbox (bash tool isolation, operator-managed via /sandbox):
enabled: true (or: false / not configured)2. Trust model framing
Print the trust-model paragraph from the top of this file (the blockquote). Then continue.
3. Prompt 1 — LAN containment + DNS policy
If `HOST_NETWORK_MODE` is true, **do not present this prompt**. Tell the operator: "Skipping LAN containment — incompatible with `network_mode: host`. Run `/hermitd:docker-setup` to switch to bridge mode if you want this hardening." Continue to step 4.
Otherwise, ask with `AskUserQuestion` (header: `"LAN containment"`):
question: "Add LAN containment with DNS policy? (firewall sidecar + DNS allowlist)"
options:
- label: "Yes — recommended (LAN block + DNS log-only)"
description: "Blocks RFC1918 + cloud metadata. DNS in log-only mode: allows everything, logs blocked queries for tuning."
- label: "Yes — strict (LAN block + DNS enforce)"
description: "Same LAN block. DNS returns NXDOMAIN for any domain not on the allowlist."
- label: "No"
description: "Skip this toggle."Map: `"Yes — recommended"` → `dns_mode: "log-only"`. `"Yes — strict"` → `dns_mode: "enforce"`. `"No"` → skip to step 4.
3-pre. Port conflict handling (only if a "Yes" option was selected above)
If the operator selected a "Yes
Run an always-on Claude Code agent on your own machine, for you or your team. Start and orchestrate sessions from chat in any project it can reach. Take over the same session in the Claude app or the CLI.
Other skills on hermitd.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Questions about docker-security.
- Which coding agents can use docker-security?
- docker-security installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

