From ee9ade4cd5815de1cc136ba31cf453cea509790b Mon Sep 17 00:00:00 2001 From: anti Date: Sun, 19 Apr 2026 18:47:03 -0400 Subject: [PATCH] feat(enroll): strip master API and frontend from agent tarball MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agents never run the FastAPI master app (decnet/web/) or serve the React frontend (decnet_web/) — they run decnet.agent, decnet.updater, and decnet.forwarder, none of which import decnet.web. Shipping the master tree bloats every enrollment payload and needlessly widens the worker's attack surface. Excluded paths are unreachable on the worker (all cli.py imports of decnet.web are inside master-only command bodies that the agent-mode gate strips). Tests assert neither tree leaks into the tarball. --- decnet/web/router/swarm_mgmt/api_enroll_bundle.py | 8 ++++++-- tests/api/swarm_mgmt/test_enroll_bundle.py | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/decnet/web/router/swarm_mgmt/api_enroll_bundle.py b/decnet/web/router/swarm_mgmt/api_enroll_bundle.py index c099515..15c3f34 100644 --- a/decnet/web/router/swarm_mgmt/api_enroll_bundle.py +++ b/decnet/web/router/swarm_mgmt/api_enroll_bundle.py @@ -61,8 +61,12 @@ _EXCLUDES: tuple[str, ...] = ( "tests", "tests/*", "development", "development/*", "wiki-checkout", "wiki-checkout/*", - "decnet_web/node_modules", "decnet_web/node_modules/*", - "decnet_web/src", "decnet_web/src/*", + # Frontend is master-only; agents never serve UI. + "decnet_web", "decnet_web/*", "decnet_web/**", + # Master FastAPI app (API, routers, master-side DB) is not run on agents. + # The `agent` / `updater` / `forwarder` commands have their own apps under + # decnet/agent, decnet/updater — they don't import decnet.web. + "decnet/web", "decnet/web/*", "decnet/web/**", "decnet-state.json", "master.log", "master.json", "decnet.tar", diff --git a/tests/api/swarm_mgmt/test_enroll_bundle.py b/tests/api/swarm_mgmt/test_enroll_bundle.py index ee5b10d..d3a085f 100644 --- a/tests/api/swarm_mgmt/test_enroll_bundle.py +++ b/tests/api/swarm_mgmt/test_enroll_bundle.py @@ -297,6 +297,11 @@ async def test_get_tgz_contents(client, auth_token, tmp_path): assert not bad.endswith(".env"), f"leaked env file: {bad}" assert ".env.local" not in bad, f"leaked env file: {bad}" assert ".env.example" not in bad, f"leaked env file: {bad}" + # Master-only trees: agents don't run the FastAPI master app or the + # React frontend, so shipping them bloats the tarball and widens the + # worker's attack surface for no benefit. + assert not bad.startswith("decnet_web/"), f"leaked frontend: {bad}" + assert not bad.startswith("decnet/web/"), f"leaked master-api: {bad}" # INI content is correct ini = tf.extractfile("etc/decnet/decnet.ini").read().decode()