EGRESS_PROXY_DEFAULT and EGRESS_PROXY_<BOT> are documented in .env.example:224-234 and docs/configuration.md:194-195, and under Compose they reach no process. docker-compose.yml contains no EGRESS reference and no env_file:, and Compose gives a container only what its environment: and env_file: blocks name. .env is read for ${...} interpolation, and there is nothing here to interpolate into.
Both arrangements are affected, for the same reason:
- Shared computer:
agent-computer/src/egress.ts:42 resolves the per-Bot name then EGRESS_PROXY_DEFAULT out of its own process.env. Neither is there, so it returns null and Chromium is launched with no proxy.
- Supervisor:
supervisor/src/index.ts:71 forwards every key starting with EGRESS_PROXY from its own environment into each computer it creates. Its environment has none, so nothing is forwarded.
Reproduced with docker compose config, which is Compose's own expansion of what each service receives. Starting from .env.example plus the two documented lines verbatim:
EGRESS anywhere in the resolved stack? NOT PRESENT ANYWHERE
agent-computer COMPUTER_TOKEN, COMPUTER_MAX_BROWSERS, COMPUTER_BROWSER_IDLE_MS
supervisor PORT, SUPERVISOR_TOKEN, COMPUTER_TOKEN, COMPUTER_IMAGE,
COMPUTER_NAMESPACE, COMPUTER_NETWORK, COMPUTER_RUNTIME, SPIRE_*
Running the real resolver against exactly that environment: egressFor("sales-bot") is null, egressFor("anything-else") is null, and the supervisor's passthrough finds 0 keys to forward. Given the same variables actually present in the process environment, the resolver returns {server: "http://sales.proxy.internal:8080"} and splits userinfo correctly, so the resolver is fine and the plumbing is the failure.
Nothing reports it. The stack starts, the browser leaves by the host, and the Computers screen says "Leaves directly" because it is reading the same empty environment. .env.example:230-231 describes the setting as attribution for a security team: "it gives a security team a per-Bot address for network rules alongside AGENT_COMPUTER_POLICY". An operator sets the proxy, believes traffic is attributable per Bot at the far side, and it is not.
It looks like an omission. git log -S'EGRESS' -- docker-compose.yml is empty, so the entries were never there and later removed, and tests/compose.test.ts asserts nothing about egress. Nothing describes egress as host-level or otherwise not meant to cross Compose.
The all-in-one image is not affected. docker/s6/s6-rc.d/computer/run runs under with-contenv, and its own comment says why: "Without it s6 starts a service with none of the container's environment". So docker run -e EGRESS_PROXY_DEFAULT=... works there, which is a fair signal that the container simply being given the variable is the intended mechanism.
The awkward part is that EGRESS_PROXY_<BOT> is derived from a Bot's id, so there is no fixed set of names to list in environment: the way COMPUTER_TOKEN is listed. Putting env_file: .env on these services would work and I would rather not: that file holds KEY_ENCRYPTION_KEY and the database URL, and the container driving a browser and running a Bot's shell is deliberately given a minimal environment (README.md:142, and the deny-list in shell.ts).
A small file of its own, given to both services and optional so a deployment with no proxy is unchanged, keeps the dynamic names working without moving any secret into that container. Happy to send a PR.
EGRESS_PROXY_DEFAULTandEGRESS_PROXY_<BOT>are documented in.env.example:224-234anddocs/configuration.md:194-195, and under Compose they reach no process.docker-compose.ymlcontains noEGRESSreference and noenv_file:, and Compose gives a container only what itsenvironment:andenv_file:blocks name..envis read for${...}interpolation, and there is nothing here to interpolate into.Both arrangements are affected, for the same reason:
agent-computer/src/egress.ts:42resolves the per-Bot name thenEGRESS_PROXY_DEFAULTout of its ownprocess.env. Neither is there, so it returns null and Chromium is launched with no proxy.supervisor/src/index.ts:71forwards every key starting withEGRESS_PROXYfrom its own environment into each computer it creates. Its environment has none, so nothing is forwarded.Reproduced with
docker compose config, which is Compose's own expansion of what each service receives. Starting from.env.exampleplus the two documented lines verbatim:Running the real resolver against exactly that environment:
egressFor("sales-bot")isnull,egressFor("anything-else")isnull, and the supervisor's passthrough finds 0 keys to forward. Given the same variables actually present in the process environment, the resolver returns{server: "http://sales.proxy.internal:8080"}and splits userinfo correctly, so the resolver is fine and the plumbing is the failure.Nothing reports it. The stack starts, the browser leaves by the host, and the Computers screen says "Leaves directly" because it is reading the same empty environment.
.env.example:230-231describes the setting as attribution for a security team: "it gives a security team a per-Bot address for network rules alongsideAGENT_COMPUTER_POLICY". An operator sets the proxy, believes traffic is attributable per Bot at the far side, and it is not.It looks like an omission.
git log -S'EGRESS' -- docker-compose.ymlis empty, so the entries were never there and later removed, andtests/compose.test.tsasserts nothing about egress. Nothing describes egress as host-level or otherwise not meant to cross Compose.The all-in-one image is not affected.
docker/s6/s6-rc.d/computer/runruns underwith-contenv, and its own comment says why: "Without it s6 starts a service with none of the container's environment". Sodocker run -e EGRESS_PROXY_DEFAULT=...works there, which is a fair signal that the container simply being given the variable is the intended mechanism.The awkward part is that
EGRESS_PROXY_<BOT>is derived from a Bot's id, so there is no fixed set of names to list inenvironment:the wayCOMPUTER_TOKENis listed. Puttingenv_file: .envon these services would work and I would rather not: that file holdsKEY_ENCRYPTION_KEYand the database URL, and the container driving a browser and running a Bot's shell is deliberately given a minimal environment (README.md:142, and the deny-list inshell.ts).A small file of its own, given to both services and optional so a deployment with no proxy is unchanged, keeps the dynamic names working without moving any secret into that container. Happy to send a PR.