@zincapp/znvault-plugin-archon
v0.5.7
Published
Archon deployment plugin for zn-vault-agent + znvault CLI (diff deploy, Prisma dynamic-secret migrations, service/reboot control)
Readme
@zincapp/znvault-plugin-archon
Archon deployment plugin for zn-vault-agent (agent side) and the znvault CLI (operator side). It deploys the archon-node control plane with a vault-native, key-less flow: diff-based file upload over SSH-CA, Prisma migrations through a short-lived dynamic-secrets lease, a 1+R canary on the API class with HAProxy drain, and service restart.
Dual entry:
- Agent (
.→dist/index.js) —createArchonPlugin(config)mounts the Fastify routes zn-vault-agent serves under/plugins/archon/*(hash manifest, diff apply, service lifecycle, guarded reboot, quiesce passthrough). - CLI (
./cli→dist/cli.js) — theznvault archon …command set.
Install
# operator machine (CLI plugin):
znvault plugin install @zincapp/znvault-plugin-archon
# each node (agent-side; node agents run with auto-update disabled):
sudo npm install -g @zincapp/znvault-plugin-archon@<version>
sudo systemctl restart zn-vault-agentPeer: @zincapp/zn-vault-agent. Requires Node ≥ 20.
CLI
znvault archon config create production --hosts … --root <checkout> # then hand-edit the multi-class config
znvault archon config validate production
znvault archon deploy credential-check production # mint + strict revoke; no migrations
znvault archon deploy run production [--dry-run|--class …|--pre-only|--skip-migrations|--skip-drain]
znvault archon deploy hashes production # preview the diff, no changes
znvault archon restart --target <host>
znvault archon reboot --target <host> --confirm <hostname> # 409 if confirm != hostname or a deploy is open
znvault archon quiesce start|status|resume --target <host>The config lives at ~/.znvault/archon/configs.json (a flat { name: config }
map). A production config has an api class (1+R canary + HAProxy haproxy
block) and a workers class (sequential, non-blocking ordering), plus a migration
block with the dynamic-secrets roleId.
Key behaviors
- Service auto-detection.
config.serviceis optional; when omitted the agent detects the single installedarchon-*.serviceon the host, so one shared fleet config works for api/worker/scheduler/backup nodes. - Writes as the app user. Files are placed with
sudo install -o archon -g archon(the app tree isarchon-owned, not agent-writable); parents are created segment-by-segment with a symlink guard. - Restart after deploy. A changed host is restarted (for serving nodes, while drained and before the health-gate) so the new code actually runs.
- Strict fleet result. A non-blocking class continues through its remaining hosts after one worker fails, but the final command exits non-zero and blocks post-deploy migrations. HAProxy reachability and complete server mapping are hard gates before the pre-deploy migration.
- PostgreSQL ownership handoff. Migration leases use a canonical
CREATE ROLE+GRANT archonlifecycle, while the Prisma connection starts withrole=archon. New DDL is therefore owned by the standing application role and the ephemeral role can be dropped cleanly. - Pre-tag credential proof.
deploy credential-checkcreates and strictly revokes one short-lived migration credential without printing it or running Prisma. A failed cleanup is a hard failure. - Tunneled lifecycle.
restart/reboot/quiesceopen an SSH-CA tunnel to the loopback-bound agent (127.0.0.1:9100).
Operator runbook
See the archon-node repo:
docs/runbooks/ZN_VAULT_ARCHON_DEPLOY.md.
Development
npm ci
npm run build # tsc → dist/ (agent index.js + CLI cli.js)
npm test # vitest
npm run lintReleases publish to npm with provenance via OIDC trusted publishing on a
v* tag push (.github/workflows/publish.yml). Publication requires reusable
CI, a tag/version/lockfile match at exact current main, one verified tarball
and a digest check immediately before publishing. Manual dispatch is disabled.
