/** * Setup Command * * Installs systemd service and creates necessary directories * for running zn-vault-agent as a system daemon. */ import type { Command } from 'commander'; export declare function registerSetupCommand(program: Command): void; /** * Build the content of the root-owned `zn-vault-agent-updater.service` unit. * * This is a `Type=oneshot` helper unit that runs the wrapper script as root, * outside the main agent unit's `ProtectSystem=strict` sandbox (which blocks the * agent from writing `/usr/lib/node_modules` + `/usr/bin` — see * INC-2026-06-12-01 P4). It is activated by the companion `.path` watcher when * an operator writes the trigger file. `ExecStartPost` restarts the agent onto * the freshly installed version. * * The unit has no `[Install]` section by design — it is activated by the `.path` * unit, not enabled directly. * * @returns The full systemd unit file content. */ export declare function buildUpdaterUnit(): string; /** * Build the root-owned `.path` unit that watches the trigger file and activates * the updater oneshot. Uses `PathExists` + delete-on-consume (the wrapper * deletes the trigger) so it cannot fire-on-enable against a stale file or loop * on a truncate. See the design spec. */ export declare function buildUpdaterPathUnit(): string; /** * Build the content of the `/etc/sudoers.d/zn-vault-agent` rules file. * * The agent runs as the unprivileged `${SYSTEM_USER}` service user under * `ProtectSystem=strict`, so it cannot self-update in process: `/usr` is * read-only in the agent's mount namespace and `sudo` only changes the uid, not * the namespace, so an in-process `sudo npm install` fails EROFS writing * `/usr/bin` (INC-2026-06-12-01). The only working path is starting the * root-owned `${UPDATER_SERVICE_NAME}.service`, which runs in its own clean * namespace — but a bare `systemctl start` is polkit-denied for the agent user * ("interactive authentication required"). * * This file grants the two NOPASSWD rules the agent's self-update relies on: * 1. Starting the updater unit (the primary, sandbox-safe path): * `sudo /usr/bin/systemctl start ${UPDATER_SERVICE_NAME}.service` * 2. A best-effort direct `npm install` for dev / non-systemd hosts that have * no updater unit and no ProtectSystem sandbox. * * The first rule MUST match the command the agent runs byte-for-byte (absolute * `/usr/bin/systemctl` path + exact unit name) — sudoers matches on the literal * command, so any divergence makes the rule a no-op. * * The file MUST be installed mode 0440, owned root:root (sudo refuses to load a * sudoers file that is group/world-writable). See `handleInstall`. * * @returns The full sudoers rules-file content. */ export declare function buildSudoersFile(includePayara?: boolean): string; /** * Build the systemd drop-in carrying every Payara-plugin requirement that the * strict base unit would otherwise block. Two parts, same incident * (INC-2026-06-22): * * 1. sudo capability — the strict base sets NoNewPrivileges=true + an empty * CapabilityBoundingSet + PrivateDevices=yes, which break sudo (cannot * setgid, audit plugin fails to init). The plugin sudoes at startup * (setenv.conf) and during deploys (asadmin), so re-grant what sudo needs. * 2. ReadWritePaths — ProtectSystem=strict makes the FS read-only except the * listed paths. The deploy writes the WAR (warPath) and Payara's domain * state + setenv.conf, which live OUTSIDE the base RW list, so every * `znvault deploy` EROFS-fails without these. /opt/payara is a symlink to * /opt/payara7 — both are listed for robustness across systemd versions. * * Non-Payara hosts keep the strict profile untouched (this drop-in is only * written when the plugin is detected). */ export declare function buildPayaraDropIn(): string; //# sourceMappingURL=setup.d.ts.map