Repository navigation
fix(worker): withhold credentials from worker bash and fail closed without a sandbox (AGT-4783) - #840
Merged
Merged
Conversation
…thout a sandbox (AGT-4783) A cgf-portal worker's `release.sh --help` ran `gh workflow run` with the daemon's GitHub login and shipped an unapproved production deploy. The bash tool now runs with an allowlisted env, a private HOME (caches re-pointed at the real dirs), an empty GH_CONFIG_DIR, no git credential helper and no ssh identity. workerSandbox: on without sandbox-exec/bwrap refuses the command instead of running it unfenced.
This was referenced Oct 21, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
On 2026-10-20 a cgf-portal worker ran
bash scripts/dev/release.sh --help. The script calledgh workflow runwith the daemon's GitHub login and shipped an unapproved production deploy (AGT-4783).A command-name fence cannot see inside a script. Comparing omp, codex and Claude Code: none of their command matchers would have stopped it either. So this PR removes the identity instead of trying to recognise the command. It is the first PR of S6 W1.
What changes
src/adapters/workerEnv.ts.buildBashToolEnvnow delegates to it. It builds the worker shell's environment as follows:SSH_AUTH_SOCK,NODE_OPTIONS, andOPENSWARM_*secrets.~/.npmrc, docker.CARGO_HOME,RUSTUP_HOME,UV_CACHE_DIR,UV_PYTHON_INSTALL_DIR,npm_config_cache,PIP_CACHE_DIRandGOCACHEare pointed back at the real directories, so builds are not cold.GH_CONFIG_DIR;credential.helperreset to none viaGIT_CONFIG_COUNT(clears osxkeychain from the system config);GIT_SSH_COMMANDwith no identity.workerSandbox: onon a host with neithersandbox-execnorbwrapnow refuses the command. It used to warn once and run unfenced. The opt-out isautonomous.workerSandbox: off, named in the refusal, the boot log,config.example.yamland the CHANGELOG. The Docker image shipsbubblewrap.buildWorkerEnv(delegated CLIs, interactive chat) is not touched. Delegated adapters in unattended runs are handled separately (AGT-4444).Measured inside the real worker sandbox (macOS, sandbox-exec)
gh auth tokengit credential fill(github.com)wrangler whoaminpm whoamiuv run --frozenin cgf-portal,cargo,node,npmcacheNot closed by this PR (honest scope)
~/Library/Preferences/.wrangler, still works. The sandbox allowsfile-read*and the network is open.workerWritableRootsstill lists the wrangler config dirs as writable. They are no longer used once HOME is private; removing them is left for the network-off PR.Behaviour reversal
#493 deliberately kept DevOps and DB credentials (e.g.
GITHUB_TOKEN,POSTGRES_DSN) in the worker shell. That test is rewritten to assert the opposite. A project whose tests need a localhost DSN will need a per-project pass-through. That will come with thesetup:config in AGT-4798, not here.Test plan
workerEnv.test.ts(9): allowlist, private HOME, re-pointed caches, gh/git/ssh overrides, and a livegit credential fill.tools.sandboxUnavailable.test.ts(2): refusal when there is no backend;offstill runs.tools.test.ts: a daemonGH_TOKENis not visible to a worker command.src/adapters, osSandbox, service, credentialProbes, worker tests: 1160 passed.scripts/release.shwrappinggh workflow run, run viaopenswarm exec --issue. Expect 0 workflow runs.