fix(security): bind orchestrator :8000 to loopback (GHSA-4f7g-w95g-5q2c)

Both deploy composes published the orchestrator API on 0.0.0.0:8000, so any
host that could reach the machine hit the control plane directly — past nginx
and, in the default header-trust posture, with no credential: read/write
runtime settings and X-Agent-Role: ceo spawn/stop. nginx reaches the API over
the internal Docker network, so a routable host publish is never needed; bind
it to 127.0.0.1. On-host debugging and normal panel operation are unchanged;
off-host access must go through nginx + cloud auth.
This commit is contained in:
Renn F
2026-07-18 07:28:14 +02:00
parent 4480dfe8d1
commit c4053d5ffd
4 changed files with 22 additions and 3 deletions
+4
View File
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
## [Unreleased]
### Security
- **Orchestrator API is no longer published on a routable host interface (GHSA-4f7g-w95g-5q2c).** Both deploy composes published the orchestrator's `:8000` on `0.0.0.0`, so anyone who could reach the host hit the control plane directly — bypassing nginx and, in the default header-trust posture (`ROBOCO_AGENT_AUTH_REQUIRED` unset, cloud auth off), reading/writing runtime settings and spoofing `X-Agent-Role: ceo` to spawn/stop agents with no credential. The publish is now bound to `127.0.0.1`; nginx reaches the API over the internal Docker network, so normal operation and on-host debugging are unchanged, while off-host access must go through nginx + cloud auth. The header-trust design itself is unchanged (it stays the deliberate local-no-login panel path); this closes the unintended off-host reachability that gave it teeth.
## [0.25.0] - 2026-07-16
### Added
+6 -1
View File
@@ -291,7 +291,12 @@ services:
- data
- render
ports:
- "8000:8000"
# Loopback-only: the orchestrator API is an unauthenticated control plane
# in header-trust mode. nginx reaches it over the internal network, so it
# never needs a routable host publish; remote access goes via nginx + cloud
# auth. A 0.0.0.0 publish exposed spawn/stop and settings-write with no
# credential to anyone who could reach the host (GHSA-4f7g-w95g-5q2c).
- "127.0.0.1:8000:8000"
environment:
# DB network isolation is LIVE in this file (postgres/redis on the
# data-only network): suppress the legacy prod-creds gate-env
+6 -1
View File
@@ -415,7 +415,12 @@ services:
- data
- render
ports:
- "8000:8000"
# Loopback-only: the orchestrator API is an unauthenticated control plane
# in header-trust mode. nginx reaches it over the internal network, so it
# never needs a routable host publish; remote access goes via nginx + cloud
# auth. A 0.0.0.0 publish exposed spawn/stop and settings-write with no
# credential to anyone who could reach the host (GHSA-4f7g-w95g-5q2c).
- "127.0.0.1:8000:8000"
environment:
# Database (use container name, not localhost)
ROBOCO_DATABASE_HOST: roboco-postgres
+6 -1
View File
@@ -415,7 +415,12 @@ services:
- data
- render
ports:
- "8000:8000"
# Loopback-only: the orchestrator API is an unauthenticated control plane
# in header-trust mode. nginx reaches it over the internal network, so it
# never needs a routable host publish; remote access goes via nginx + cloud
# auth. A 0.0.0.0 publish exposed spawn/stop and settings-write with no
# credential to anyone who could reach the host (GHSA-4f7g-w95g-5q2c).
- "127.0.0.1:8000:8000"
environment:
# Database (use container name, not localhost)
ROBOCO_DATABASE_HOST: roboco-postgres