agent-bot/src/index.ts and agent-langgraph/src/index.ts serve POST /ag-ui with no authentication check. Every request is passed straight to runAgent(input) regardless of caller, so any process that can reach the Bot's port issues runs against the deployment's model credential. docker-compose.yml:162 binds ${BOT_PORT:-4200}:4200 to 0.0.0.0 in the shipped configuration, so on a default laptop deployment the endpoint is reachable from anything on the host's network and any container on the compose network. agent-computer/src/index.ts and supervisor/src/index.ts both require a shared secret at boot and validate it on every request; the two Bots do not.
Verified against main at 581e4cc with the shipped docker-compose.yml:
| request |
result |
POST /ag-ui, no headers, valid AG-UI body |
HTTP 200, RUN_STARTED, model called |
POST /ag-ui with Authorization: Bearer wrong |
HTTP 200, same |
GET /health |
HTTP 200 (correctly open) |
MANAGED_AGENT_TOKEN is not read anywhere in either Bot, and server/src/agents/runtime-agents.ts does not attach any authentication header when it calls the managed endpoint. The boundary is absent on both sides rather than misconfigured, so no environment change closes it.
Any local process, whether a co-tenant on the machine, a container on the same Docker network, or a browser tab that guesses the URL, can spend the deployment's OpenAI, Anthropic, or Google budget and read the responses. forwardedProps and tools are attacker-controlled fields in the AG-UI body, so the model can be steered into any tool the client-side loop will execute.
This is the opposite direction to #34, which added per-agent callback tokens for the Bot→server path. That change does not cover requests going the other way, from the server into a Bot's /ag-ui, which is what this issue is about.
Fix ready; PR to follow.
agent-bot/src/index.tsandagent-langgraph/src/index.tsservePOST /ag-uiwith no authentication check. Every request is passed straight torunAgent(input)regardless of caller, so any process that can reach the Bot's port issues runs against the deployment's model credential.docker-compose.yml:162binds${BOT_PORT:-4200}:4200to0.0.0.0in the shipped configuration, so on a default laptop deployment the endpoint is reachable from anything on the host's network and any container on the compose network.agent-computer/src/index.tsandsupervisor/src/index.tsboth require a shared secret at boot and validate it on every request; the two Bots do not.Verified against
mainat 581e4cc with the shippeddocker-compose.yml:POST /ag-ui, no headers, valid AG-UI bodyRUN_STARTED, model calledPOST /ag-uiwithAuthorization: Bearer wrongGET /healthMANAGED_AGENT_TOKENis not read anywhere in either Bot, andserver/src/agents/runtime-agents.tsdoes not attach any authentication header when it calls the managed endpoint. The boundary is absent on both sides rather than misconfigured, so no environment change closes it.Any local process, whether a co-tenant on the machine, a container on the same Docker network, or a browser tab that guesses the URL, can spend the deployment's OpenAI, Anthropic, or Google budget and read the responses.
forwardedPropsandtoolsare attacker-controlled fields in the AG-UI body, so the model can be steered into any tool the client-side loop will execute.This is the opposite direction to #34, which added per-agent callback tokens for the Bot→server path. That change does not cover requests going the other way, from the server into a Bot's
/ag-ui, which is what this issue is about.Fix ready; PR to follow.