Skip to content

fix(deploy): the durable server provisions from its own command, not a postStart hook - #77

Merged
antoinetoussaint-byte merged 1 commit into
mainfrom
probes/no-exec
Oct 10, 2026
Merged

antoinetoussaint-byte merged 1 commit into
mainfrom
probes/no-exec

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

What

A durable (restricted) render's container command, provision/server.sh, now does three things:

  1. starts the server;
  2. runs the unchanged provision/provision.sh (durable mode) against it, with the script and key name passed as $1 and $2 (data, never script text);
  3. waits on the server.

If provisioning fails, the script stops the server and exits non-zero, so the container restarts and provisions again, just as a failed hook did. A termination trap waits for the server to shut down cleanly. The restricted render carries no exec hook. The local dev render keeps its postStart hook, since no admission runs there.

Why

The hosted-gcp-staging cell's execution admission, platform-obin-approved-execution (Deny), refuses any pod whose container declares an exec probe or exec lifecycle hook. Its message says to put start-up work in the approved image. Staging's other stores are already down on this rule after a node upgrade. saas's Vault survives only because its pod has not been recreated yet.

Verified

  • go test ./... passes, including the Docker integration tests against real Vault containers: first boot, idempotent re-provisioning, restart with state preserved, a refused access token, refusal to initialize over an existing init record, and the PGP-encrypted recovery key.
  • Mutation-checked: a provisioning failure that leaves the server running fails the tests.

Trade-off, stated

The hook kept the container out of Running until provisioning had succeeded. Now, on a brand-new empty volume only, readiness, which needs an initialized, unsealed, active server, can pass a few seconds before the transit key and the KV mount exist. A restarted Vault already holds that state, and provisioning is then a no-op.

Not in this PR

golangci-lint reports one pre-existing errcheck finding. This change adds none, and CI does not run that linter. It is left out to keep this outage fix reviewable.

Classification

Fix at the owner.

🤖 Generated with Claude Code

…a postStart hook

A cell's execution admission refuses any container with an exec probe or
hook, so a durable (restricted) Vault could not start on staging. The
container command, provision/server.sh, now starts the server, runs the
unchanged provision/provision.sh (durable mode, script and key name as $1
and $2) against it, and waits on it; a provisioning failure stops the
server and exits non-zero so the container restarts and provisions again,
as a failed hook did. A termination trap waits for the server to shut down.
The local dev render keeps its postStart hook (no admission there).

The Docker harness provisions through the container's own command: it waits
for 'vault: provisioned' or the container's exit; idempotence is re-checked
by running the script again in the live server; refusing to initialize over
an init record is checked by the record being untouched. Mutation-checked:
a provisioning failure that leaves the server running fails the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte merged commit 06049e4 into main Oct 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants