Initial commit

This commit is contained in:
2026-05-07 22:45:36 -04:00
commit c45f384fb8
21 changed files with 2727 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
Decisions and state changes are logged in `JOURNAL.md`. Research notes live in `research/`.
+5
View File
@@ -0,0 +1,5 @@
# Journal
Append-only stream of thought. Newest entries on top. Each entry is a timestamp
followed by freeform prose. Tag entries with `[name](tag://name)` links under
the header — only when a coherent theme emerges. Otherwise just write.
View File
View File
@@ -0,0 +1,58 @@
# Host Dispatch to Container Agents
## Question
Can host Claude decide which claude-bottle container to spin up for a task, while guaranteeing the work executes in the container and not on the host?
## Claude Code Agent Mechanisms
Claude Code provides two mechanisms for defining reusable agent behavior:
**Skills** (`.claude/skills/<name>/SKILL.md`) run inline in the main conversation context. They're reusable workflows invoked via `/skill-name`, with optional tool pre-approval.
**Subagents** (`.claude/agents/<name>.md`) run in an isolated context window with a custom system prompt and a declared tool allowlist. They're invoked by natural language, `@agent-name`, or `claude --agent`. The `tools:` frontmatter is enforced — the subagent cannot call tools not in the list. (See [Claude Code subagents docs](https://code.claude.com/docs/en/sub-agents.md), "Choose the subagent scope" and "Write subagent files" sections.)
"Isolated context window" means only conversational isolation (fresh LLM state, summarized output). It is not process, filesystem, or network isolation. Subagents still run on the host with full user permissions.
## The Reliability Problem
The previous approach used an MCP server to bridge host Claude and claude-bottle containers. It failed because host Claude had both work-capable tools (Edit, Write, Bash) and MCP dispatch tools. Claude could choose to do the work itself rather than dispatch, with no enforcement mechanism to prevent it.
## Why Tool Restriction Solves It
Claude Code's subagent `tools:` allowlist is architecturally enforced — not a prompt-level suggestion. If the host subagent is defined with only container-dispatch tools and no Edit/Write/Bash, it is incapable of doing implementation work. Dispatch becomes the only available path.
## Reliable Dispatch Architecture
Three pieces in combination give a 100% guarantee:
1. **Restricted host subagent** — a `.claude/agents/claude-bottle-dispatch.md` with `tools:` limited to MCP container tools and git-read operations. No Edit, Write, or arbitrary Bash.
2. **MCP server** — exposes tools the restricted host can call:
- `list_agents()` — available agents from the manifest (host Claude decides which to use)
- `run_agent(agent_name, task)` — starts a container non-interactively, returns a job ID
- `get_status(job_id)` — check running/done
- `get_output(job_id)` — read results
3. **Non-interactive container run mode**`cli.sh run <agent> "<task>"` passes the task to `claude --print` inside the container and captures output. Currently `cli.sh start` is interactive only; this mode does not yet exist.
## Proposal
Build host-dispatch-to-container in two deliverables:
**Deliverable 1: Non-interactive run mode for claude-bottle**
Extend `cli.sh` with a `run <agent> <task>` subcommand. Starts the container, writes the task prompt to a file inside it (same `docker cp` pattern used for `--append-system-prompt-file`), invokes `claude --print` with the prompt, streams stdout back to the host, and exits when Claude finishes. Results committed and pushed from inside the container as usual.
**Deliverable 2: MCP server wrapping claude-bottle**
A minimal MCP server (bash or node) exposing `list_agents`, `run_agent`, `get_status`, `get_output`. Registered in the host Claude Code settings so a restricted dispatch subagent can call it.
The combination enforces the container boundary at the tool layer, not the prompt layer — making it structurally impossible for host Claude to do implementation work itself.
**Critical:** the tool restriction only applies within the dispatch agent's context. A normal Claude session has its full toolset and may never invoke the dispatch agent regardless of its description. The dispatch agent must be the *entry point* for the session, not an optional subagent a full-tool host might call. Two ways to enforce this:
- Launch with `claude --agent claude-bottle-dispatch` — makes the dispatch agent the primary agent for the session.
- Set `agent: claude-bottle-dispatch` in the project `.claude/settings.json` — same effect automatically for any `claude` invocation in that directory.
Without one of these, the guarantee does not hold.
@@ -0,0 +1,76 @@
# Landscape: containerized Claude Code agent tools
Research into whether claude-bottle is redundant with existing projects, and
whether it's worth publishing.
## Summary
The "Claude Code in Docker" space is active but not saturated. claude-bottle
occupies a distinct position: no surveyed project combines all five of its
defining features. Publishing is likely worthwhile, with the main risk being
claudebox expanding to absorb the same niche.
## Closest competitor: claudebox
[RchGrav/claudebox](https://github.com/RchGrav/claudebox) is the most
feature-complete analog. It runs Claude Code in Docker with per-project
isolated images, 15+ pre-configured dev-language profiles, and per-project
network firewall allowlists. Actively maintained with multiple forks.
What it lacks: manifest-driven named agents, per-agent env resolution modes
(prompt / host-forward / literal), skill directory injection, per-agent system
prompts, SSH-agent forwarding without copying private keys, home+project
manifest merge.
## Other surveyed projects
- **textcortex/claude-code-sandbox → spritz** — evolved toward
Kubernetes-native multi-agent infra; not bash-first or local-Docker.
Original sandbox repo is archived.
- **trailofbits/claude-code-devcontainer** — devcontainer config for security
audits; not a general agent launcher.
- **Several small solo repos** (arezi/claude-sandbox, nkrefman/claude-sandbox,
VishalJ99/claude-docker) — lightweight Docker wrappers with no multi-agent
config layer.
- **Docker's official sandbox templates** — launch-and-run Dockerfiles plus an
npm-based runtime; not a manifest-driven fleet manager.
## Adjacent (different model)
- **dagger/container-use** (mid-2025) — exposes an MCP server so the *agent*
spins up its own containers with Git worktrees. Inverted model vs. claude-bottle
(agent controls container rather than being launched into one by a manifest).
Still marked early-development.
- **E2B, Northflank, Cloudflare Sandbox SDK** — cloud-hosted SaaS sandbox
runtimes; fundamentally different architecture.
## What no found project does
None combine:
1. Named-agent JSON manifest with per-agent env resolution (prompt / host-forward / literal)
2. Claude Code skills directory injection
3. Per-agent system prompts
4. SSH-agent key forwarding without copying private keys into the container
5. Home + project manifest merge
## Publishing verdict
Worth publishing. Differentiators that matter to the target audience (power
users running parallel Claude Code sessions with distinct personas/tooling):
- The bash-first, low-dependency design — competitors are npm-based or
Kubernetes-native.
- Named agents with distinct skills and system prompts, not just language profiles.
- SSH forwarding without key copying.
Main risk: claudebox adds manifest/agent config. The space is moving fast
enough that publishing sooner is better if establishing prior art matters.
Discovery will be slow without active promotion; an Anthropic Discord post or
HN "Show HN" would do most of the work.
## Caveats
- GitHub search cannot surface private or very new repos comprehensively.
- Counts (stars, forks) were not confirmed for every project.
- Research conducted 2026-05-07; the space moves fast.
@@ -0,0 +1,231 @@
# Local vs. Remote Agent Execution: Security & Privacy Tradeoffs
Research notes on when to run containerized Claude Code agents on a remote machine
outside the local network versus inside it, focusing on security and privacy concerns.
Relevant to a potential claude-bottle extension for remote agent execution.
---
## The core mental model
The topology decision isn't "local = safe, remote = dangerous." The real variables are:
**what can the agent reach if compromised**, **what's on the host if the container
escapes**, and **whether credentials are short-lived and scoped**.
---
## Threat landscape by topology
### Local (current claude-bottle model)
- Container escape → developer laptop → `~/.ssh`, `~/.aws`, browser cookies, Keychain, everything
- Outbound: Docker containers have full internet access by default; no egress monitoring on most home networks
- Lateral movement: compromised container can reach the LAN — NAS, other machines, internal services
- Notable: CVE-2025-59536 (CVSS 8.7, Feb 2026) — a poisoned `.claude/settings.json` in a repo gives RCE when Claude Code opens it. `--dangerously-skip-permissions` removes the last gate.
- Supply chain: MCP servers, skills, and npm packages pulled during agent execution. ~20% of ClawHub skills were found malicious in early 2026.
**What local topology protects:**
- No inbound attack surface — nothing listening on a public port
- Secrets stay physically on your hardware; no transit risk
- Network egress bounded by the host router
### Remote machine
- New inbound attack surface (SSH/API port must be open; CISA notes exploitation of remote access vulns within 913 days of disclosure)
- Secrets must travel from local to remote — each transit is a new exposure class
- If the VM has a cloud IAM role attached → blast radius includes cloud APIs (S3, RDS, IAM, etc.)
- Compromised remote host can read env vars injected into containers, intercept docker exec sessions, exfiltrate skills and prompts
- **Worst case:** a remote VM connected back to the LAN via VPN is the worst of both worlds — internet-facing attack surface + full LAN access. This pattern should never be built.
- Multiple agents sharing the same remote host creates cross-tenant bleed risk.
**What remote topology can offer:**
- Better isolation from the developer laptop — a compromised container doesn't reach `~/.ssh` or local credentials unless explicitly forwarded
- Ephemeral compute — a cloud VM torn down after each session leaves no persistent attack surface
- Cloud-native network controls (Security Groups, VPC firewall, PrivateLink) can be more granular than home router rules
- VPC flow logs + CloudTrail give an audit trail that a home network doesn't
---
## Data sensitivity — when "on-prem" matters
Data that should not leave the local network absent extraordinary controls:
| Data type | Why |
|---|---|
| Private SSH keys | If copied to remote, stored outside your control; lateral movement via key reuse |
| Secrets forwarded into containers (API tokens, OAuth tokens) | In-transit exposure; remote machine persistence risk |
| Source code under NDA or with unreleased IP | Contractual and competitive risk |
| PHI (HIPAA) | Requires BAA with every system that touches it; standard cloud VMs don't qualify |
| PII of EU residents (GDPR) | Cannot legally transit US infrastructure without SCCs |
| Internal API credentials for LAN systems | Sending to a remote agent that can reach back via VPN creates a remote-controlled pivot |
Data that can go remote with proper controls:
- Public open-source code
- Non-sensitive project scaffolding
- Prompts that don't contain embedded secrets
- Derived outputs (build artifacts, test results) that don't contain source data
---
## Blast radius comparison
### Worst case: local container compromise
1. Container escape via kernel exploit → developer laptop
2. From laptop: `~/.ssh/id_rsa`, `~/.aws/credentials`, browser session cookies, macOS Keychain, `~/.claude`
3. Lateral movement to LAN — internal services, NAS, other dev machines
4. Outbound: anything the home/office network allows
### Worst case: remote container compromise
1. Container escape → remote host
2. From remote host: host environment credentials, any attached IAM role, secrets in the host filesystem
3. If a VPN or SSH tunnel links remote machine to local network → full lateral movement back through that tunnel
4. Cloud API access if the VM has IAM permissions → S3, RDS, EC2, Secrets Manager, etc.
**Remote blast radius is potentially larger than local if:**
- The remote VM has cloud IAM permissions broader than the local laptop environment
- The remote machine is connected back to the local network via VPN (creating a pivot)
- Multiple agents share the same remote host
**Remote blast radius is smaller if:**
- The remote VM is strictly isolated (no VPN back to LAN)
- IAM role is locked to minimum necessary permissions
- Remote host is ephemeral and torn down after each session
Key insight: once a container is compromised via prompt injection, the blast radius is dominated by what the agent *can reach*, not by where it physically runs. Studies have measured an 82.4% inter-agent compromise rate in multi-agent systems.
---
## Credentials and secrets
### Local topology (current claude-bottle)
- Secrets live in the host environment or are prompted from `/dev/tty`
- Forwarded to containers via `-e NAME` (not `=value`), never on argv, never in env-files for secrets
- On container teardown, secrets are gone from that process space
- Risk: container escape to host reaches the host env where the parent process ran
### Remote topology
Secrets must travel from their source to the remote machine. Mechanisms in increasing security order:
1. **SSH env forwarding (`AcceptEnv`/`SendEnv`)** — secrets in plaintext in the SSH session; logged by some SSH daemon configurations
2. **Encrypted orchestration channel** — secrets encrypted in transit, but remote machine must decrypt and expose them in memory
3. **Vault/cloud secrets manager + dynamic credentials** — remote machine fetches its own short-lived secrets; local machine never sends secrets at all (best option)
An 8,640x reduction in abuse window comes from switching from 90-day keys to 15-minute tokens. Static long-lived tokens (`CLAUDE_CODE_OAUTH_TOKEN`, `GITLAB_TOKEN`) are the biggest risk in a remote topology.
**Proxy-inject pattern:** agent makes unauthenticated requests; a proxy outside the container injects credentials per-request. The container never sees the raw token. Anthropic's secure deployment docs recommend this pattern.
---
## Egress and exfiltration risk
### Local topology
- Monitoring: whatever the home/office router supports — usually minimal
- Containment: `--network none` + a proxy socket provides the strongest containment; claude-bottle does not currently do this
- DLP: essentially none unless specifically deployed on the LAN
- Domain fronting risk: even allowlisted-domain proxies can be bypassed via domain fronting — an agent that can reach `api.anthropic.com` could relay data to an attacker-controlled backend through that domain
- **claude-bottle today: containers have full outbound internet access. No egress restrictions.**
### Remote topology (cloud VM)
- VPC flow logs capture every connection attempt by IP/port — better than most home networks if configured
- Security Groups can allowlist specific endpoints; a NAT gateway can be locked down
- DLP tooling is more mature in cloud environments (AWS Macie, GCP DLP API, Cloudflare AI Gateway)
- But only if configured. A raw cloud VM with default settings has worse egress monitoring than a corporate network.
Strongest exfiltration controls for either topology:
1. `--network none` in Docker + a unix socket proxy that enforces domain allowlists
2. TLS inspection at the proxy to defeat domain fronting
3. Audit log all outbound traffic at the proxy
---
## Compliance
### HIPAA
- PHI must stay within HIPAA-covered infrastructure. Standard commercial cloud VMs require a signed BAA with the provider. AWS Bedrock, Azure OpenAI, and Google Cloud can be configured with BAA coverage; a generic EC2 cannot.
- If the agent processes any PHI, the remote machine must be in a HIPAA-qualified environment.
- "Minimum necessary" rule: an agent with broad filesystem access to a repo containing PHI violates this unless carefully scoped.
### GDPR
- EU personal data cannot legally be sent to US infrastructure without Standard Contractual Clauses or adequacy decisions.
- Local execution (if the developer is EU-based) sidesteps this. Remote execution on a US cloud VM requires SCCs.
### SOC2
- No specific data residency mandate, but all infrastructure that touches in-scope data must implement the trust criteria. A remote VM needs audit logs, access controls, and continuous monitoring — more operational overhead than local execution.
---
## Decision heuristics
| Scenario | Recommendation |
|---|---|
| Solo developer, personal projects, no regulated data | Local is fine; add egress proxy for defense-in-depth |
| Regulated data (HIPAA, GDPR, SOC2) | Local unless the remote environment is fully qualified |
| Long-running automated tasks, no secrets in content | Remote VM acceptable with egress controls and ephemeral lifecycle |
| Parallel agent fleet | Remote VM cluster with per-agent IAM roles, strict egress, centralized secret management |
| Agent receives credentials that give network access to LAN | Keep local; never build a VPN-connected remote agent that can pivot back to the LAN |
| Source code with embedded secrets (`.env`, API keys in config) | Local only, or sanitize before sending to remote |
| Lack infrastructure maturity for proper remote config | Local — a poorly configured VM is strictly worse than a well-configured local container |
---
## Concrete recommendations if extending claude-bottle for remote
1. **Never build the VPN-pivot pattern.** A remote agent connected back to the LAN via VPN is the worst of both worlds. If a remote agent needs LAN resources, expose those through a narrow API, not a VPN.
2. **Add `--network none` + a proxy socket, even locally first.** The single highest-leverage change available right now. Bounds egress to allowlisted domains, prevents arbitrary exfiltration regardless of topology. Anthropic's secure deployment docs show exactly how to do this.
3. **Use dynamic, short-lived credentials for the remote context.** Replace static tokens with per-task dynamically issued credentials (Vault with approle auth, or cloud workload identity federation). This eliminates the "credential concentration on remote host" problem.
4. **Proxy-inject credentials; don't send them to the container.** The proxy runs on the remote host (not in the container); the credential lives only in the proxy process.
5. **Scope IAM/cloud permissions to the minimum.** No `*:*` policies. No admin roles on the VM.
6. **Make the remote VM ephemeral.** Spin it up for the session, tear it down when done. No persistent credentials or data between sessions.
7. **Enable VPC flow logs and forward them somewhere.** Going remote buys you egress monitoring you don't have locally — but only if configured.
8. **Validate hooks before execution.** `init-work` / `init-free-agent` copies a project into the container. That project may contain poisoned `.claude/settings.json` hooks (CVE-2025-59536 vector). `--dangerously-skip-permissions` removes the last gate; consider validating hooks before execution.
---
## Bottom line
For the current claude-bottle use case (developer feature implementation, no regulated data,
single developer), local execution is the right default. The biggest unaddressed risk
right now isn't topology — it's that containers have unrestricted outbound internet access.
Adding `--network none` + a proxy socket would be higher-leverage than any topology change.
Remote execution becomes worth the complexity for parallelism at scale, long-running
unattended tasks, or strict separation of agent compute from developer hardware — but
only with egress controls, ephemeral lifecycle, and dynamic credential management in place.
---
## Sources
- Penligent AI — AI Agents Hacking in 2026: Defending the New Execution Boundary
- Repello AI — The Agentic AI security threat landscape in 2026
- arxiv 2601.17548 — Prompt Injection Attacks on Agentic Coding Assistants
- Unit42 (Palo Alto) — Navigating Security Tradeoffs of AI Agents
- Trend Micro — Unveiling AI Agent Vulnerabilities Part III: Data Exfiltration
- Help Net Security — 29 million leaked secrets in 2025: AI agents credentials are out of control
- GitGuardian — Short-Lived Credentials in Agentic Systems: A Practical Trade-off Guide
- Aembit — Securing AI Agents Without Static Credentials
- Anthropic Docs — Securely Deploying AI Agents
- Anthropic Engineering — Claude Code Sandboxing
- TrueFoundry — Claude Code Sandboxing: Network Isolation, File System Controls
- TrueFoundry — LLM Deployment in Regulated Industries: HIPAA, SOC2 & GDPR Playbook
- MindStudio — AI Agent Compliance: GDPR SOC 2 and Beyond
- OX Security — The Mother of All AI Supply Chains: Critical MCP Vulnerability
- The Hacker News — Anthropic MCP Design Vulnerability Enables RCE
- Straiker — Agent Hijacking: How Prompt Injection Leads to Full AI System Compromise
- Seraphic Security — Secure Remote Access Best Practices 2025