Files
sencho/backend/src/pilot
Anso 0947a80cda fix(mesh): trust central for cross-node dial auth and regenerate overrides at boot (#1014)
Two bugs in the same Phase D follow-up surface, fixed together because they
both block declaring B-verify complete on the production fleet.

Cross-node mesh dials returned `denied` at the agent. The pilot's
`tcp_open` handler in `agent.ts::resolveMeshTarget` consulted the local
SQLite `mesh_stacks` table, which is no longer written to under the
post-Phase D control plane (state lives only on central). Drop the check.
The pilot tunnel JWT (scope `pilot_tunnel`, signed with central's
`auth_jwt_secret`) authenticates the caller; the same trust model already
applies to filesystem ops, exec, and container control over the same
tunnel.

Threat-model trade-off: a leaked `pilot_tunnel` JWT or compromised
central can now dial any compose-managed service on the pilot. Containers
without `com.docker.compose.project` + `com.docker.compose.service`
labels remain unreachable via this path.

`MeshService.start()` did not regenerate compose override files at boot.
After a Sencho restart with missing overrides on disk, meshed user
containers had no `extra_hosts` / `networks: [sencho_mesh]` injection
until each stack was opted out and back in. Add `regenerateAllOverrides()`
that walks every `mesh_stacks` row and re-pushes via `pushOverrideToNode`.
Best-effort: per-stack failures log to the mesh activity buffer;
`MeshService.start()` is fire-and-forget at startup so a slow remote
node does not delay boot.

Tests:
- `pilot-agent-mesh-resolve.test.ts` (new): mocks dockerode and proves
  `resolveMeshTarget` no longer returns `denied` with an empty
  `mesh_stacks` table.
- `mesh-service.test.ts`: three new cases for `regenerateAllOverrides` -
  fan-out across the fleet, skip when `senchoIp` is null, log per-stack
  warning on push failure without throwing.
2026-05-09 03:27:39 -04:00
..