- Book: Ship It — the pragmatic startup tech stack
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
You run archon serve on a dev box so you can watch your coding-agent workflows in a browser. Anyone else on that network can now start those workflows too, send your agent messages, and click Approve on the actions it paused to ask you about. No password is involved, because in a default install there isn't one.
That is the finding behind CVE-2026-111322, published by VulnCheck on October 15, 2026 against Archon, the open-source workflow engine that drives Claude Code, Codex and Pi through YAML-defined development workflows. The repo has 23.7k stars. As of October 16, its latest release is still v0.11.1, the last affected version, and the repo's security page lists no published advisory.
What the advisory says
VulnCheck's advisory covers Archon >= 0.2.13, <= 0.11.1, classes it as CWE-306, "Missing Authentication for Critical Function", and scores it 9.3 under CVSS 4.0. The CVE record mirrored by Strix carries a CVSS 3.1 score of 9.8 (AV:N/AC:L/PR:N/UI:N), with NVD's own analysis still pending.
In VulnCheck's words, the /api/* control API binds to "0.0.0.0 by default", and an attacker with network access can send messages to the coding agent, "which runs with bypassPermissions", to run commands on the host as the Archon user. The finding is credited to the researcher who published it as hieuPenguinnn.

The agent's control plane, reachable by anything on the network.
Why the default install is open
The researcher's writeup points at three files at tag v0.11.1, and you can read them yourself. The server picks its bind address in index.ts:
const hostname = process.env.HOST || '0.0.0.0';
The project's own .env.example documents that default and its escape hatch: "Set to 127.0.0.1 to restrict to localhost only." The default port is 3090.
Authentication is opt-in. The header of auth/config.ts says web auth is off by default and is enabled only when "BOTH a Postgres DATABASE_URL and a BETTER_AUTH_SECRET are present." The gate itself is one line:
return isWebAuthEnabled(env)
&& env.ARCHON_WEB_AUTH_REQUIRED !== 'false';
And the middleware in routes/api.ts waves the request through when that returns false:
if (!isApiGateEnabled()) return next();
The researcher describes the out-of-the-box install as SQLite with no secret, and that takes the open path. So a stock install answers /api/* from any machine that can reach port 3090, with no credentials.
What an attacker can do, and the part that's disputed
The writeup lists what any client that reaches port 3090 can do on a default install, with no credentials: start workflow runs, create conversations and inject messages the agent treats as operator input, approve or reject the agent's paused actions, and, where per-user provider keys apply, connect or disconnect them. The named routes include POST /api/workflows/<name>/run, POST /api/conversations/<id>/message and POST /api/workflows/runs/<runId>/approve.
Read the writeup before you repeat the "RCE" headline, though. The researcher states: "This is not remote code execution on the host." They also say "Runtime validation was NOT performed" and that the example requests "were not executed against a live instance." Their own badge reads high, not critical. VulnCheck's advisory goes further and ties the flaw to command execution through the agent's bypassPermissions mode.
Both readings can be true at once. The HTTP request doesn't hand anyone a shell by itself. What they get is the steering wheel of an agent that may already be allowed to run shell commands. Claude Code's permission-modes docs describe bypassPermissions as the mode where "Everything" runs without asking, recommended for "Isolated containers and VMs only", and warn that it "offers no protection against prompt injection or unintended actions." How bad a hijacked run is depends on what your workflows and your agent are allowed to do.
There's no public exploit yet: as of October 16, The Hacker Wire lists no public proof of concept and says the CVE is not in CISA KEV. The route list in a public writeup is most of a recipe, so don't wait for one.
Lock it down until a fix ships
Start by checking whether Archon is listening on every interface. On macOS or Linux:
lsof -nP -iTCP:3090 -sTCP:LISTEN
# Linux alternative:
ss -ltnp 'sport = :3090'
An address of *:3090 or 0.0.0.0:3090 means every interface. 127.0.0.1:3090 means loopback only.
1. Bind to loopback. Set the variable the project already documents in your .env, then restart archon serve:
HOST=127.0.0.1
The writeup notes this removes network reach even though the gate stays disabled. With the gate off, any process on the same machine can still drive the API, so treat loopback as a stopgap. If you run Archon in Docker, the container has to listen on all of its own interfaces, so do the restriction at publish time instead. Assuming the container serves on 3090:
docker run -p 127.0.0.1:3090:3090 <your-archon-image>
2. Turn the gate on. Per auth/config.ts, the /api/* gate needs both a Postgres URL and a signing secret of at least 32 characters, and .env.example suggests generating it with openssl rand -base64 32:
DATABASE_URL=postgresql://archon:CHANGE_ME@localhost:5432/archon
BETTER_AUTH_SECRET=<output of: openssl rand -base64 32>
Do not set ARCHON_WEB_AUTH_REQUIRED=false unless an authenticating proxy really does sit in front. The writeup says a deployment with both variables set is not affected.

Loopback first, then a real gate in front of the API.
3. Put a proxy with auth in front of anything shared. Archon's SECURITY.md already says: "When deploying the server publicly, use the Caddy reverse proxy with authentication (see deploy/docker-compose.yml)". A team server is a public deployment for this purpose, even if "public" means the office Wi-Fi.
Then check from a second machine, with ARCHON_HOST set to the dev box's LAN address. /api/health is on the gate's public allowlist in routes/api.ts, so it's a pure reachability test:
curl -sS -m 3 "http://$ARCHON_HOST:3090/api/health"
If that answers from another machine after step 1, your bind didn't take.
Agent harnesses are servers now
The researcher's suggested fix is small: default to 127.0.0.1, require a local token on mutating routes even when web auth is off, and warn at startup on a non-loopback bind without auth. It's the same advice you'd give any dashboard, except this dashboard fronts an agent with a shell, your provider keys and an Approve button.
This isn't the first unauthenticated-backend finding against Archon either. In May, OX Security wrote up CVE-2025-69443 in the earlier Archon OS line (0.1.0 through 0.3.11), where a backend port with "no CORS protection and no authentication" could be reached from a malicious web page. Per OX, the maintainer's position then was that the app is meant to run locally.
So, a question for you: how many agent tools on your machine run a local HTTP server right now, and do you know which address each one binds to?
If this was useful
Most of this post is about the gap between "it runs on my laptop" and "it's safe on a network": bind addresses, auth that defaults to off, a proxy in front. Ship It is my book about that whole stretch for a small team, from hosting and auth to CI/CD and monitoring, so that the next self-hosted tool you stand up starts closed.
I also build Hermes IDE, so weigh this with that in mind: it's free, source-available (BSL 1.1), runs on macOS, Windows and Linux, and gives each agent task its own branch and worktree. It's on GitHub, and it isn't affiliated with Archon, Anthropic, OpenAI or any agent vendor.

Top comments (0)