Skip to content

Security: Alfredvc/ccairgap

Security

SECURITY.md

Security policy

Reporting a vulnerability

Open a GitHub issue. Include:

  • Affected version (ccairgap --version)
  • Host OS
  • Reproduction steps or PoC
  • Expected vs. actual behavior

Threat model

Full design: docs/SPEC.md. Summary below.

In scope — not accepted

Any write to the host filesystem outside the paths enumerated in docs/SPEC.md §"Host writable paths". Specifically, the container must not be able to mutate:

  • Real git repositories passed via --repo / --extra-repo (only ccairgap/<id> ref creation via host-side git fetch on exit is permitted).
  • Host ~/.claude/, ~/.claude.json, plugin marketplace repos.
  • Any --ro reference path.
  • Any host path not explicitly opted-in via --mount.

A bug that lets the container escape those constraints is a vulnerability. Report it.

Out of scope — accepted risk

  • Exfiltration. Anything the container can read (host ~/.claude/ contents, RO-mounted repos, reference paths, secrets in env) may be sent over the network. The container has unrestricted outbound HTTPS. If your threat model requires network egress control, do not run this tool.
  • Container escape. Not addressed by this project. We follow Docker defaults (no --privileged, no SYS_ADMIN, no docker.sock mount, --cap-drop=ALL, non-root user) but do not harden further. A kernel or Docker runtime exploit is out of scope — take it up with Docker / the kernel.
  • --mount <path> writes. User-declared live RW bind mounts bypass the host-write invariant for exactly the path given. Using --mount is opt-in; any host mutation via that path is expected behavior.
  • --dangerously-skip-permissions semantics inside the container. Claude Code runs with all permissions by design. Inside-container destruction of the session clone, session scratch, /output, and declared --mount targets is expected.

Clipboard passthrough risks

Clipboard passthrough (see docs/SPEC.md §"Clipboard passthrough") introduces two accepted attack surfaces.

  • Sensitive clipboard images persisted briefly to disk. The host-side watcher writes the current clipboard image to $SESSION/clipboard-bridge/current.png on every clipboard change. If the user copies a sensitive screenshot (password UI, 2FA code) while a ccairgap session is running, it lives on disk at user-readable perms until the clipboard changes to non-image content or the session ends. Mitigation: --no-clipboard; session scratch is removed on handoff/recover.

  • Always-on host-side watcher. A background process runs as the host user for the CLI lifetime, reading the clipboard on every poll (macOS/X11) or clipboard-change event (Wayland/WSL2). Runs as the host user (required to read the clipboard) and is not sandboxed. A compromise of ccairgap could repurpose it as a persistent clipboard reader. Mitigation: --no-clipboard.

Explicitly NOT risks in v2 (they were in v1):

  • Host-clipboard write-back from the container — no clipboard-write tool, no compositor access.
  • X11 full-session exposure — container has no $DISPLAY, no /tmp/.X11-unix/ mount.
  • Wayland client capabilities — container is not a Wayland client.
  • Broader /mnt/wslg mount — /mnt/wslg is not mounted.

Hardening posture

  • docker run --cap-drop=ALL --security-opt=no-new-privileges --user $(id -u):$(id -g) --rm
  • Container runs as the host UID/GID directly. There is no in-container privilege step, no usermod/chown, no gosu. --cap-drop=ALL plus no-new-privileges is preserved end-to-end.
  • No --privileged, no SYS_ADMIN, no docker.sock mount
  • Host repos RO-mounted; container-written copies live in a session clone
  • Credentials surface via a single RO bind (/host-claude-creds); ~/.claude/.credentials.json is excluded from the general /host-claude mount
  • macOS credentials materialized from Keychain to session scratch at mode 0600, deleted with the session on exit

Verifying the published container image

The published image at ghcr.io/alfredvc/ccairgap:<version> carries a SLSA build-provenance attestation produced by GitHub Actions during the release workflow. Verify before use:

gh attestation verify oci://ghcr.io/alfredvc/ccairgap:<version> --owner alfredvc

A successful verification asserts the image was built by .github/workflows/release.yml from a tagged commit on this repository. Verification is optional — the CLI never enforces it. Users who skip it implicitly trust the GHCR registry's authentication of the image. Users who want a fully reproducible local build can pass --rebuild (skips the registry pull and rebuilds from the bundled docker/Dockerfile + docker/entrypoint.sh shipped in the npm package).

Supported versions

Pre-1.0. Only the latest minor receives security fixes. After 1.0, the latest two minors will be supported.

Version Supported
0.1.x Yes
< 0.1 No

Scope of this policy

Covers the ccairgap CLI, its shipped docker/Dockerfile, and docker/entrypoint.sh. Bugs in upstream Claude Code, Docker, Node, or the host kernel are not covered here — report those upstream.

There aren’t any published security advisories