carlos / platform Public

doc-engine routes are reachable from the internet: engines should be fleet-internal Issue open

Claimed by claude~paul@keymail.dev 3 days ago

Problem. The doc_engine capability (internal/caps/render.go, README "App capabilities") fences an engine's egress away from private networks. It says nothing about who can call the engine. A doc-engine route is a route like any other, so the box's public edge serves it, and nothing on main makes a route internal-only. The only gate is whatever auth the engine applies itself (Gotenberg: basic auth, often none). A leaked credential, or an operator who skips auth, publishes a Chromium/LibreOffice renderer to the internet: resource abuse at best, and an SSRF engine whose only remaining reach is the public internet and its own box's loopback.

Why it matters now. #328 (an isolated tenant reaching its operator's private Gotenberg) gets a per-app egress allow as the near-term answer. The platform's own engine story should not be "put it on the internet behind basic auth", which is what an isolated tenant has to do today to reach a doc-engine route.

Proposed direction (needs a spec):

  • A doc-engine route is fleet-internal: the edge refuses its hostname on public listeners.
  • Consuming apps get an operator grant to use a named engine, per app (the same exception to the --host-only grant rule that #328's egress allow takes).
  • The platform carries the call: a socket bound into each consuming instance's namespace (as the per-instance control socket is), relayed by the box's edge to the engine's box over the fleet's private path. Isolated tenants then reach an engine without any private address opened in their fence.
  • Provider-neutral: the relay is the edge's, not a VPC feature.

Not blocking: Tito's Gotenberg is outside the platform, so #328's egress allow unblocks it independently.

LLM

Spec in progress on branch design-fleet-internal-engines (docs/superpowers/specs/2026-10-21-fleet-internal-engines-design.md). Paul's rulings 2026-10-21: (R1) a route whose live release declares doc_engine is internal, no separate registration for that; (R2) unit-backed apps are not callers in this spec. Rev 2 answers Astra round 1 (reject, 4 P1s, all accepted); round 2 running.

LLM

Paul's rulings 2026-10-21 (cont.): (R3) an engine's home box is dedicated and the platform enforces it: no proxying route outside the engine's group on that box; public ingress beyond the edge's ports is a stated, surveyed precondition. (R4) review end: one Astra round on rev 13, then Paul's read; the plan opens with a simulation of invariant I1 and the dedicated-box rule. Spec rev 13 (ee51da7f) on design-fleet-internal-engines.

LLM

Paul approved spec rev 14 (24ac41ac) on 2026-10-21. Next: implementation plan, task 1 a simulation of I1 and the dedicated-box rule.

LLM

Paul's ruling R5 (2026-10-21): engines.json grant records go stale 10 minutes after signing; the console re-signs every 2 minutes and on every change (closes the bucket-writer replay window). Plan 1 (simulation) built and task-reviewed; final review found 5 model/spec gaps (unfenced new NULL group, --public/launch race, expiry grace, residual guards, replay exclusion); one fix wave running.

LLM

Census (#280): Paul, as census owner, ruled overlay design-fleet-internal-engines accepted as proposed (2026-10-21): internal/sim/engines/mutate.sh external accepted-legacy like hostlife's harness; test-only envelope pinned. Merge of design-fleet-internal-engines follows green CI.