Follow-up to #7678 / #7679. Those fixed every path that broke agent startup under filesystem.allowWrite. Two AWF-internal writes under /tmp remain. Neither stops the container from starting, so the live integration test passes, but one silently weakens security.
1. /tmp/awf-lib — token protection and the gh proxy wrapper degrade silently
containers/agent/entrypoint.sh stages three things into /host/tmp/awf-lib for use inside the chroot:
one-shot-token.so (LD_PRELOAD token protection)
- the Claude
CLAUDE_CODE_API_KEY_HELPER
gh-cli-proxy-wrapper.sh, prepended to PATH as /tmp/awf-lib/gh
filesystem.allowWrite narrows the /tmp bind to read-only, so these writes fail. The code degrades gracefully instead of failing, which is why nothing is red. Observed directly in run 32681985728 with allowWrite: ["<tmpdir>/agent"]:
[entrypoint][WARN] Could not copy one-shot-token library to /tmp/awf-lib
[entrypoint][WARN] Token protection will be disabled (tokens may be readable multiple times)
So enabling filesystem.allowWrite currently disables one-shot token protection and the gh CLI proxy wrapper, with only a warning. That is a security regression triggered by opting into a security feature.
The comment at entrypoint.sh:642 still claims /tmp/awf-lib/ is "always writable", which is no longer true.
Suggested fix: relocate to /run/awf-lib, matching /run/awf-init (#7679) and /run/awf-cmd-$$.sh (0cb81ea). /run inside the chroot is the container's own writable rootfs, not a host bind, so it is unaffected by any host write policy. ~49 literal references in entrypoint.sh.
Worth confirming /run is not mounted noexec in any supported topology before relying on it for the LD_PRELOAD .so and the gh wrapper — the command-script move only proves it is writable and readable.
2. /tmp/awf-runner-bin — ARC/DinD staging mount
src/services/agent-volumes/workspace-mounts.ts:52 mounts the staged runner binary at /tmp/awf-runner-bin/<name>, nested under the narrowable /tmp bind. stageHostFile writes to the AWF work dir, not to /tmp/awf-runner-bin, so the mountpoint does not exist on the host and runc cannot create it under a read-only parent.
Only reachable with --docker-host-path-prefix (ARC/DinD split filesystem) and filesystem.allowWrite, so it did not surface in CI. gh-aw uses both, so the intersection is realistic.
/tmp/awf-runner-bin is baked into entrypoint.sh in ~9 places including PATH construction and error text, so this is an image-contract change and should ship in lockstep with a release.
Suggested checklist
Follow-up to #7678 / #7679. Those fixed every path that broke agent startup under
filesystem.allowWrite. Two AWF-internal writes under/tmpremain. Neither stops the container from starting, so the live integration test passes, but one silently weakens security.1.
/tmp/awf-lib— token protection and theghproxy wrapper degrade silentlycontainers/agent/entrypoint.shstages three things into/host/tmp/awf-libfor use inside the chroot:one-shot-token.so(LD_PRELOAD token protection)CLAUDE_CODE_API_KEY_HELPERgh-cli-proxy-wrapper.sh, prepended toPATHas/tmp/awf-lib/ghfilesystem.allowWritenarrows the/tmpbind to read-only, so these writes fail. The code degrades gracefully instead of failing, which is why nothing is red. Observed directly in run 32681985728 withallowWrite: ["<tmpdir>/agent"]:So enabling
filesystem.allowWritecurrently disables one-shot token protection and theghCLI proxy wrapper, with only a warning. That is a security regression triggered by opting into a security feature.The comment at
entrypoint.sh:642still claims/tmp/awf-lib/is "always writable", which is no longer true.Suggested fix: relocate to
/run/awf-lib, matching/run/awf-init(#7679) and/run/awf-cmd-$$.sh(0cb81ea)./runinside the chroot is the container's own writable rootfs, not a host bind, so it is unaffected by any host write policy. ~49 literal references inentrypoint.sh.Worth confirming
/runis not mountednoexecin any supported topology before relying on it for the LD_PRELOAD.soand theghwrapper — the command-script move only proves it is writable and readable.2.
/tmp/awf-runner-bin— ARC/DinD staging mountsrc/services/agent-volumes/workspace-mounts.ts:52mounts the staged runner binary at/tmp/awf-runner-bin/<name>, nested under the narrowable/tmpbind.stageHostFilewrites to the AWF work dir, not to/tmp/awf-runner-bin, so the mountpoint does not exist on the host andrunccannot create it under a read-only parent.Only reachable with
--docker-host-path-prefix(ARC/DinD split filesystem) andfilesystem.allowWrite, so it did not surface in CI. gh-aw uses both, so the intersection is realistic./tmp/awf-runner-binis baked intoentrypoint.shin ~9 places includingPATHconstruction and error text, so this is an image-contract change and should ship in lockstep with a release.Suggested checklist
/tmp/awf-libto/run/awf-lib/runis notnoexecfor the LD_PRELOAD.soand theghwrapperentrypoint.sh:642/tmp/awf-runner-bin(move, or pre-create the host mountpoint)filesystem.allowWritepolicyallowWrite, so this cannot regress silently again