LearnNewsExamplesServices
Frontmatter
id17516
titleLocal Agent OS rejects its own Compose service hostnames
stateClosed
labels
bugaitestingagent-os
assigneesneo-gpt-emmy
createdAtAug 22, 2026, 12:41 AM
updatedAtAug 22, 2026, 2:52 PM
githubUrlhttps://github.com/neomjs/neo/issues/17516
authorneo-gpt-emmy
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 22, 2026, 2:52 PM

Local Agent OS rejects its own Compose service hostnames

Closed Backlog/active-chunk-18 bugaitestingagent-os
neo-gpt-emmy
neo-gpt-emmy commented on Aug 22, 2026, 12:41 AM

Context

During the 2026-08-22 local Agent OS update, all four Neo containers reached the exact live revision 0e072f05cddf23567d71adbeb136b14fc337e19d and Docker health. Two cross-service paths still failed:

  • Fleet's service-owned plane client dialed http://ingress:8080/mc/mcp and received 403 Invalid Host: ingress, leaving the wake push lane honestly unarmed.
  • Orchestrator deployment-state direct probes reached kb-server / mc-server but received Invalid Host: kb-server and Invalid Host: mc-server, so they fell back to Docker-only service evidence.

The container healthchecks stayed green because they dial loopback. Green containers therefore did not exercise the Compose-DNS Host-header boundary.

The Problem

ai/deploy/docker-compose.local-agent-os.yml declares NEO_FLEET_PLANE_INTERNAL_HOSTS=ingress, which authorizes Fleet's outbound plain-HTTP endpoint policy. It does not configure the receiving MCP servers' inbound Host allowlist.

The inbound authority already exists: ai/configBase.mjs exposes mcp.allowedHosts through NEO_MCP_ALLOWED_HOSTS, consumed by TransportService.computeAllowedHosts. The local overlay never passes that leaf to KB or MC, so the deployment advertises internal routes its receivers reject.

The Architectural Reality

The two allowlists are intentionally separate:

  • Fleet's planeInternalHosts vouches for a confidential Compose-network hop before dialing.
  • Each MCP server's mcp.allowedHosts admits exact HTTP Host values and protects against DNS rebinding.

The fix belongs in the local deployment overlay, not in global transport defaults, Caddy rewriting, or a weaker server guard. Exact service names remain deployment-local and fail closed everywhere else.

The Fix

Update ai/deploy/docker-compose.local-agent-os.yml with exact service-local inbound names:

  • kb-server: NEO_MCP_ALLOWED_HOSTS=kb-server
  • mc-server: NEO_MCP_ALLOWED_HOSTS=mc-server,ingress

Extend the owning deployment composition tests so rendered local Compose must carry those exact values and must not use a wildcard.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
local KB inbound Host allowlist mcp.allowedHosts / NEO_MCP_ALLOWED_HOSTS admit exact kb-server Compose DNS Host implicit loopback/public URL hosts remain overlay comments rendered Compose + unit assertion
local MC inbound Host allowlist same transport leaf admit exact mc-server and ingress Hosts implicit loopback/public URL hosts remain overlay comments rendered Compose + unit assertion
Fleet wake plane session Fleet service credential + MC caller-owned subscription boot/connect arming can reach MC through ingress poll-digest stays truth lane existing Fleet JSDoc fresh-container authenticated init
deployment-state direct probes orchestrator bridge KB/MC direct probes return service evidence Docker inspect remains available existing bridge JSDoc post-deploy snapshot/log receipt

Decision Record impact

aligned-with ADR 0014 — this completes the existing local multi-container topology; it changes no service ownership or transport policy.

Acceptance Criteria

  • Local overlay passes exact kb-server to KB's NEO_MCP_ALLOWED_HOSTS.
  • Local overlay passes exact mc-server,ingress to MC's NEO_MCP_ALLOWED_HOSTS.
  • No wildcard, public-host broadening, or global default change is introduced.
  • Owning unit coverage parses/renders the overlay and asserts both exact service-local values.
  • Focused unit coverage and repository preflight are green.
  • Post-merge deployment validation: Fleet's authenticated plane init succeeds through ingress, and Orchestrator logs no Invalid Host warning for KB/MC direct probes.

Out of Scope

  • Chroma, ingress, or volume recreation.
  • Caddy Host-header rewriting.
  • Public/cloud deployment hostnames.
  • The pre-existing off-host-backup and heavy-maintenance-starvation findings.
  • Changing Fleet's caller-owned wake-subscription model.

Avoided Traps

  • Wildcard Host admission — defeats the DNS-rebinding boundary.
  • Treating outbound endpoint permission as inbound admission — two authorities with different jobs.
  • Caddy-only rewrite — would hide the Fleet symptom while leaving Orchestrator direct probes broken.
  • Untracked local override — makes the next sanctioned rebuild silently regress.

Related

Observed while completing the repository-epoch/container-pin work tracked by #17376.

Live latest-open sweep: latest 20 open issues checked at 2026-08-21T22:39Z; no equivalent found. Recent A2A claim sweep found no competing lane.

Origin Session ID: 7287162e-14b1-44ca-b7d5-a2854211828f

Retrieval Hint: "local Agent OS Invalid Host ingress kb-server mc-server NEO_MCP_ALLOWED_HOSTS Fleet wake push"

tobiu referenced in commit 109663e - "fix(agentos): admit local compose service hosts (#17516) (#17517)" on Aug 22, 2026, 2:52 PM
tobiu closed this issue on Aug 22, 2026, 2:52 PM