* fix: shadow .env file in container to prevent agents from reading secrets The main agent's container mounts the project root read-only, which inadvertently exposed the .env file containing API keys. Mount /dev/null over /workspace/project/.env to shadow it — secrets are already passed via stdin and never need to be read from disk inside the container. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: adapt .env shadowing and runtime for Apple Container Apple Container (VirtioFS) only supports directory mounts, not file mounts. The previous /dev/null host-side mount over .env crashes with VZErrorDomain "A directory sharing device configuration is invalid". - Dockerfile: entrypoint now shadows .env via mount --bind inside the container, then drops privileges via setpriv to the host UID/GID - container-runner: main containers skip --user and pass RUN_UID/RUN_GID env vars so entrypoint starts as root for mount --bind - container-runtime: switch to Apple Container CLI (container), fix cleanupOrphans to use container list --format json - Skill: add Dockerfile and container-runner.ts to convert-to-apple-container skill (v1.1.0) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: revert src to Docker runtime, keep Apple Container in skill only The source files should remain Docker-compatible. The Apple Container adaptations live in the convert-to-apple-container skill and are applied on demand. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1.8 KiB
1.8 KiB
Intent: container/Dockerfile modifications
What changed
Updated the entrypoint script to shadow .env inside the container and drop privileges at runtime, replacing the Docker-style host-side file mount approach.
Why
Apple Container (VirtioFS) only supports directory mounts, not file mounts. The Docker approach of mounting /dev/null over .env from the host causes VZErrorDomain Code=2 "A directory sharing device configuration is invalid". The fix moves the shadowing into the entrypoint using mount --bind (which works inside the Linux VM).
Key sections
Entrypoint script
- Added:
mount --bind /dev/null /workspace/project/.envwhen running as root and.envexists - Added: Privilege drop via
setpriv --reuid=$RUN_UID --regid=$RUN_GID --clear-groupsfor main-group containers - Added:
chownof/tmp/input.jsonand/tmp/distto target user before dropping privileges - Removed:
USER nodedirective — main containers start as root to perform the bind mount, then drop privileges in the entrypoint. Non-main containers still get--userfrom the host.
Dual-path execution
- Root path (main containers): shadow .env → compile → capture stdin → chown → setpriv drop → exec node
- Non-root path (other containers): compile → capture stdin → exec node
Invariants
- The entrypoint still reads JSON from stdin and runs the agent-runner
- The compiled output goes to
/tmp/dist(read-only after build) node_modulesis symlinked, not copied- Non-main containers are unaffected (they arrive as non-root via
--user)
Must-keep
- The
set -eat the top - The stdin capture to
/tmp/input.json(required because setpriv can't forward stdin piping) - The
chmod -R a-w /tmp/dist(prevents agent from modifying its own runner) - The
chown -R node:node /workspacein the build step