Skip to content

feat(claude-code): bundle security-guidance and claude-security plugins - #199

Merged
gatezh merged 2 commits into
masterfrom
feat/claude-code-security-plugins
Oct 7, 2026
Merged

gatezh merged 2 commits into
masterfrom
feat/claude-code-security-plugins

Conversation

@gatezh

@gatezh gatezh commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

What

Add Anthropic's security-guidance and claude-security plugins to the claude-code init-plugins.sh template, and bake Python 3 into the image so they actually run.

Why

Both plugins are in claude-plugins-official (already registered), so the template change is just two entries. Both run on Python, though, and the image had no Python. node:24-trixie-slim ships no interpreter. Without it, security-guidance's PostToolUse/Stop hooks exit 1 on every edit and turn, and claude-security can't run its scan scripts. The sandbox firewall blocks deb.debian.org, so consumers can't apt-get install Python at runtime. It has to live in base, the same reasoning as openssh-client (#110).

Changes

  • init-plugins.sh: install security-guidance@claude-plugins-official and claude-security@claude-plugins-official
  • Dockerfile (base stage, so both targets get it): add python3 (3.13 on trixie) and python3-venv. The plugins only use the standard library. python3-venv provides ensurepip, which security-guidance needs to build its claude-agent-sdk venv in ~/.claude/security/ (persisted by the ~/.claude volume).
  • CI verify (ci.yml + build-claude-code.yml, all 4 matrix entries): assert python3 -c 'import ensurepip'
  • claude-code/README.md: add python3 to the tools table, add both plugins to the bundled-plugins table, and add a note on security-guidance's runtime SDK download
  • Size roadmap (docs/plans/…image-size-roadmap.md): record the Python cost in the core-image table and the measurements log

Notes

  • Runtime SDK download: the agentic commit reviewer in security-guidance needs claude-agent-sdk (a ~100 MB wheel that bundles its own Claude Code binary), fetched from PyPI on first session start into the ~/.claude volume, not the image. SECURITY_GUIDANCE_DISABLE=1 does not skip that bootstrap. In the sandbox: the default-deny firewall blocks the fetch. The plugin then falls back to the single-call diff review, and edit-time pattern warnings and Stop reviews keep working. The README tells sandbox consumers to allowlist pypi.org + files.pythonhosted.org if they want the full reviewer.
  • Cost: security-guidance runs an LLM diff review at the end of every turn and on each commit/push. Consumers can turn it off with SECURITY_GUIDANCE_DISABLE=1 (or the finer-grained ENABLE_* vars) or drop it from their init-plugins.sh copy.
  • Footprint: apt python3 + python3-venv with --no-install-recommends adds about 41 MB on disk, measured on a clean node:24-trixie-slim. That's the smallest set that works:
    • python3-minimal (+18 MB) lacks http/urllib, which both plugins import.
    • python3-venv (+5 MB) is cheaper than python3-pip (+15 MB) for the SDK venv.
    • The byte-compiled stdlib (12 MB) stays. Stripping it makes every hook call recompile imports as node (about 50 ms → 240 ms per call), and security-guidance fires on every edit.
    • Alternatives like uv/mise standalone builds or an official python image stage are all larger, and apt is the canonical route on Debian.
  • This changes only the template. Existing consumers pick the plugins up by copying the new entries into their own init-plugins.sh. The Python they need arrives with the next image pull.

Fits the layer/cache work from #183 and #196

Rebased onto master (incl. #196 and #195). Built master and this branch side by side, both targets:

Check master this PR
default / sandbox on disk 2.32 / 2.31 GB 2.37 / 2.37 GB
default ↔ sandbox shared layers (#196) 22 of 23 22 of 23
Layers that change on a Claude Code version bump (#183) 2 of 23 2 of 23
Base apt layer 165 MB 205 MB
  • Python goes into the existing apt RUN in base. That layer rarely changes and sits above the shared stage, so both targets share it and no layer is added. Adding it busts the cache below it once; after that, Claude Code bumps still rebuild only the Claude Code and agent-browser layers.
  • apt runs with the existing BuildKit cache mounts and --no-install-recommends, so no apt lists or caches ship in the image. The compressed download grows by about 13 MB (gzip of the added files).
  • No new ARG, no Renovate entry: apt packages are unpinned by policy (.hadolint.yaml ignores DL3008).

Verification (local, amd64)

  • Built default and sandbox targets after the rebase; the CI verify commands from both ci.yml and build-claude-code.yml pass on each
  • Mounted the plugins into the sandbox image and ran their hooks:
    • security-guidance PostToolUse hook flagged a yaml.load() write (.py) and an innerHTML write (.js)
    • claude-security banner hook rendered (exit 0)
    • python3 -m venv + pip work
  • hadolint (with repo .hadolint.yaml) and actionlint are clean

gatezh added 2 commits October 6, 2026 14:58
- Install security-guidance and claude-security from claude-plugins-official
  in the init-plugins.sh template
- Bake python3 + python3-venv (~+41 MB) into the base stage: both plugins' hooks and
  scripts need Python, and the image had none (security-guidance's hooks
  would exit 1 on every edit); the sandbox firewall blocks runtime apt
- Assert python3/ensurepip in the image verify steps (ci.yml + build workflow)
- Document both plugins and the sandbox PyPI allowlist note in the README
… cost in size roadmap

- SECURITY_GUIDANCE_DISABLE stops the reviews but not the SessionStart venv
  bootstrap (~100 MB claude-agent-sdk wheel into ~/.claude); say so
- Log python3/python3-venv (+41 MB disk, ~13 MB compressed, layer sharing
  and per-bump rebuild unchanged) in the image size roadmap
@gatezh
gatezh force-pushed the feat/claude-code-security-plugins branch from 244c7cc to 1faeed1 Compare October 6, 2026 21:03
@gatezh
gatezh merged commit 63e84e0 into master Oct 7, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant