fix(secrets): wrap an image server's own command, not just entrypoint #121

Merged
michal merged 1 commits from fix/injector-image-server-argv into main 2026-08-21 10:14:42 +00:00
Owner

docmost and my-home-assistant rendered their secrets but never picked them up: wrapCommand consulted only server.entrypoint for non-package servers, so with it unset the wrapper was skipped and the container ran its normal command, never sourcing the file. Silent by construction — the agent succeeds, the file exists, the server just starts with empty credentials.

An explicit command on an image server is already a complete command line and should be wrapped verbatim. Now branches on the three real shapes. Seven tests; reintroducing the old logic fails two.

docmost and my-home-assistant rendered their secrets but never picked them up: wrapCommand consulted only `server.entrypoint` for non-package servers, so with it unset the wrapper was skipped and the container ran its normal command, never sourcing the file. Silent by construction — the agent succeeds, the file exists, the server just starts with empty credentials. An explicit `command` on an image server is already a complete command line and should be wrapped verbatim. Now branches on the three real shapes. Seven tests; reintroducing the old logic fails two.
michal added 1 commit 2026-08-21 10:14:41 +00:00
fix(secrets): wrap an image server's own command, not just entrypoint
Some checks failed
CI/CD / lint (pull_request) Successful in 1m25s
CI/CD / test (pull_request) Successful in 1m32s
CI/CD / typecheck (pull_request) Successful in 3m0s
CI/CD / smoke (pull_request) Failing after 2m0s
CI/CD / build (pull_request) Successful in 4m34s
CI/CD / publish (pull_request) Has been skipped
913c0fbdc6
Migrating docmost and my-home-assistant, both rendered their secret and
neither picked it up. The pod spec showed why:

  command: (empty)
  args:    ["node","build/index.js"]
  server.entrypoint: (unset)

wrapCommand consulted only `server.entrypoint` for non-package servers, so
with `entrypoint` unset it returned undefined, the wrapper was skipped
entirely, and the container ran its normal command — which never sourced
/vault/secrets/<name>. The failure is silent by construction: the agent
init container succeeds, the file is there, and the server simply starts
with empty credentials.

An explicit `command` on an image server is already a complete command
line — mcpd's exec mode would run exactly it — so it should be wrapped
verbatim. `entrypoint` is only needed when there is no command at all and
the image's own ENTRYPOINT would take over.

Now branches on the three real shapes: package server (prepend the runner
entrypoint mcpd owns), image + command (use verbatim), image only (require
the declared entrypoint).

Seven tests, one per shape plus the two undefined cases. Reintroducing the
old logic fails two of them — checked before keeping.

Both servers were rolled back to secretDelivery: env and are healthy; they
can migrate once this ships.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018vybEitX4FykeMatKe5Xki
michal merged commit c79bdab51b into main 2026-08-21 10:14:42 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: michal/mcpctl#121