Files
nanoclaw/.claude/skills/convert-to-apple-container/modify/src/container-runner.ts.intent.md
gavrielc bae8538695 Fix/shadow env in container (#646)
* 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>
2026-03-02 13:28:28 +02:00

1.8 KiB

Intent: src/container-runner.ts modifications

What changed

Updated buildContainerArgs to support Apple Container's .env shadowing mechanism. The function now accepts an isMain parameter and uses it to decide how container user identity is configured.

Why

Apple Container (VirtioFS) only supports directory mounts, not file mounts. The previous approach of mounting /dev/null over .env from the host causes a VZErrorDomain crash. Instead, main-group containers now start as root so the entrypoint can mount --bind /dev/null over .env inside the Linux VM, then drop to the host user via setpriv.

Key sections

buildContainerArgs (signature change)

  • Added: isMain: boolean parameter
  • Main containers: passes RUN_UID/RUN_GID env vars instead of --user, so the container starts as root
  • Non-main containers: unchanged, still uses --user flag

buildVolumeMounts

  • Removed: the /dev/null/workspace/project/.env shadow mount (was in the committed 37228a9 fix)
  • The .env shadowing is now handled inside the container entrypoint instead

runContainerAgent (call site)

  • Changed: buildContainerArgs(mounts, containerName)buildContainerArgs(mounts, containerName, input.isMain)

Invariants

  • All exported interfaces unchanged: ContainerInput, ContainerOutput, runContainerAgent, writeTasksSnapshot, writeGroupsSnapshot, AvailableGroup
  • Non-main containers behave identically (still get --user flag)
  • Mount list for non-main containers is unchanged
  • Secrets still passed via stdin, never mounted as files
  • Output parsing (streaming + legacy) unchanged

Must-keep

  • The isMain parameter on buildContainerArgs (consumed by runContainerAgent)
  • The RUN_UID/RUN_GID env vars for main containers (consumed by entrypoint.sh)
  • The --user flag for non-main containers (file permission compatibility)