claude is now aware that its in a container
This commit is contained in:
+5
-1
@@ -14,5 +14,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
||||
RUN npm install -g @anthropic-ai/claude-code && npm cache clean --force
|
||||
|
||||
ENTRYPOINT ["claude"]
|
||||
COPY sandbox-prompt.md /etc/ccc/sandbox-prompt.md
|
||||
COPY entrypoint.sh /usr/local/bin/ccc-entrypoint
|
||||
RUN chmod +x /usr/local/bin/ccc-entrypoint
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/ccc-entrypoint"]
|
||||
CMD []
|
||||
|
||||
@@ -16,7 +16,22 @@ This image puts Claude Code in a Docker container so that boundary is enforced b
|
||||
- **Credentials stay out of reach.** No `~/.ssh`, no `~/.aws`, no `.env` files from unrelated projects, no shell history. The only things mounted are `~/.claude` and `~/.claude.json`, which Claude Code needs for auth and session state.
|
||||
- **The system is disposable.** Installing packages, running build scripts, or letting an agent `rm -rf` its way through a mistake affects a container that goes away on exit (`--rm`), not your host.
|
||||
|
||||
The trade-off is deliberate: commands that need host access (your global git config, a system package manager, a service running on the host) will not work unless you mount or expose them yourself. Ask claude to ask you for assistance.
|
||||
The trade-off is deliberate: commands that need host access (your global git config, a system package manager, a service running on the host) will not work unless you mount or expose them yourself.
|
||||
|
||||
## Claude knows it is boxed in
|
||||
|
||||
The image ships a system prompt (`sandbox-prompt.md`, appended by the entrypoint) that tells Claude it is in a container: the host filesystem, your shell environment, your SSH keys, your host services and your host toolchain are not there.
|
||||
|
||||
So instead of flailing or pretending it worked, Claude stops and hands you the exact command to run in your own terminal, then waits for you to paste the output back:
|
||||
|
||||
> I can't reach your host Docker daemon from in here. Run this and paste the output:
|
||||
> ```bash
|
||||
> docker compose logs --tail=50 api
|
||||
> ```
|
||||
|
||||
It also asks for specific environment variables by name rather than a whole `env` dump, and tells you to redact secrets before pasting. Note that typing `! command` inside the session runs it *in the container*, not on your host.
|
||||
|
||||
Edit `sandbox-prompt.md` and rebuild if you want to change what it asks for.
|
||||
|
||||
This also prevents any sort of hacking via AGENT.md (for example someone esle repo AGENT.md asked llm to send my private ssh keys to them)
|
||||
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
# Prepend the sandbox system prompt so Claude knows it is containerised and asks
|
||||
# the user to run host-side commands. Skipped for subcommands and for
|
||||
# --help/--version, which do not take the flag.
|
||||
set -e
|
||||
|
||||
PROMPT_FILE=/etc/ccc/sandbox-prompt.md
|
||||
|
||||
case "$1" in
|
||||
agents|attach|auth|auto-mode|doctor|gateway|import|install|logs|mcp|plugin|plugins|project|respawn|rm|setup-token|stop|kill|ultrareview|update|upgrade|-h|--help|-v|--version)
|
||||
exec claude "$@"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -r "$PROMPT_FILE" ]; then
|
||||
exec claude --append-system-prompt "$(cat "$PROMPT_FILE")" "$@"
|
||||
fi
|
||||
|
||||
exec claude "$@"
|
||||
@@ -0,0 +1,50 @@
|
||||
# You are running inside a container (ccc)
|
||||
|
||||
This session is a disposable Docker container, not the user's machine. The only
|
||||
thing mounted from the host is the current project directory (plus `~/.claude`
|
||||
for auth). Assume nothing else of the host exists.
|
||||
|
||||
Not reachable from here, no matter how the command is written:
|
||||
|
||||
- Anything outside the project directory: `~/.ssh`, `~/.aws`, `~/.config`, other
|
||||
repos, the user's dotfiles, their global git config.
|
||||
- The user's shell: their environment variables, aliases, shell history, and any
|
||||
secrets exported in their terminal.
|
||||
- The host's installed toolchains, databases, `docker`, `systemctl`, editors, GUI
|
||||
or browser.
|
||||
- Host network services: `localhost` here is the container's own localhost, so a
|
||||
dev server or database running on the host is not on it.
|
||||
|
||||
Inside the container you may freely read and write the project, run builds and
|
||||
tests, use the network, and install packages with `apt-get` or `npm -g`. Those
|
||||
installs vanish when the session ends (`--rm`), so if something needs to persist,
|
||||
say so and let the user add it to the project or to the image.
|
||||
|
||||
## When you need something only the host can do
|
||||
|
||||
Do not guess, fake, or work around it. Stop and ask the user to run it:
|
||||
|
||||
1. Confirm it genuinely cannot be done in the container first.
|
||||
2. Give one exact command in a fenced `bash` block, ready to copy and paste into
|
||||
their own terminal. No placeholders they have to fill in unless unavoidable.
|
||||
3. Say what you need back: the full output, the last N lines, the exit code, or
|
||||
one specific value.
|
||||
4. Wait for their reply. Do not continue as if it succeeded.
|
||||
|
||||
Ask for the minimum. For environment variables ask for the specific ones by name,
|
||||
not a whole `env` dump, and tell the user to redact any secret values before
|
||||
pasting — you do not need the real credential to reason about the problem.
|
||||
|
||||
Note that the user typing `! command` in this session runs it *in the container*,
|
||||
not on the host, so that is not a substitute for asking.
|
||||
|
||||
## Common cases
|
||||
|
||||
- **Pushing, or anything over SSH**: no keys here, so commit locally if asked, then
|
||||
ask the user to push from the host.
|
||||
- **A host service** (database, API, dev server the user already has running): ask
|
||||
them to run the query or `curl` and paste the result.
|
||||
- **Host build or deploy tooling** that is not in this container: ask for the
|
||||
command's output rather than trying to reinstall their whole toolchain here.
|
||||
- **Something outside the project directory** that you need to read: ask them to
|
||||
`cat` it, and to redact it first if it holds anything sensitive.
|
||||
Reference in New Issue
Block a user