Require signed agent releases (Refs #64)

This commit is contained in:
2026-10-09 20:36:18 -04:00
parent df0d395138
commit 6f71822d41
24 changed files with 984 additions and 107 deletions
+26 -5
View File
@@ -2,7 +2,8 @@
The controller uses SvelteKit, TypeScript and SQLite (`better-sqlite3`), with the
Node adapter and server-sent events. The host agent uses Python 3's standard
library and runs as a systemd service; hosts do not need Node.js.
library and runs as a systemd service; release verification calls `gpgv`.
Hosts do not need Node.js.
Agents connect outbound to the controller over HTTPS and manage Docker/Plutainer
and local RCON on each host. The controller owns fleet metadata and queues; it
@@ -10,7 +11,9 @@ does not require a Docker socket or direct access to host filesystems.
## Run locally
Use Node.js 22.13+ (the container uses Node.js 22), npm and Python 3.
Use Node.js 22.13+ (the container uses Node.js 22), npm and Python 3. Install
GnuPG's `gpg`, `gpg-agent` and `gpgv` to run real release-signing integration tests; local test
runs skip those tests when either executable is absent.
```sh
npm ci
@@ -89,8 +92,10 @@ npm run build
The [Gitea Actions workflow](../../.gitea/workflows/ci.yml) runs these checks on
every push and pull request after `npm ci`. It uses a Node.js 22 Debian container
with Python 3 and native build tools for `better-sqlite3`. The runner must support
Docker jobs with the `ubuntu-latest` label. `npm run check` runs before the tests
with Python 3, `gpg`, `gpg-agent`, `gpgv` and native build tools for `better-sqlite3`. Signing
tests create disposable keys in temporary directories; CI never receives release
private keys. The runner must support Docker jobs with the `ubuntu-latest` label.
`npm run check` runs before the tests
to generate the SvelteKit configuration needed in a fresh checkout. Application
tests use two workers in CI to bound resource use for database-heavy fixtures.
The build step runs the same `npm run build` command used by the Dockerfile,
@@ -118,7 +123,23 @@ Dependency security checks must include development dependencies: use `npm audit
without `--omit=dev`.
`npm run dev` and `npm run build` regenerate the downloadable agent, installer,
standalone updater and checksum manifest. Builds also bundle report workers
standalone updater and checksum manifest. Packaging preserves an existing
`static/agent/manifest.json.sig` only when its manifest bytes remain identical;
changes to the agent, updater or installer remove the stale signature. Builds
never sign, and hosts reject unsigned releases while retaining installed code.
Finalize and review release code, run `npm run agent:package`, and explicitly
sign it on the offline publisher machine:
```sh
python3 agent/sign_release.py --gnupghome /secure/electric-cherry-signing --fingerprint FULL_SIGNING_KEY_FINGERPRINT
```
Commit or distribute the signed public artifacts before building the controller
image from the same source revision. Keep the signing home outside the repository, Docker context, controller
and CI. Follow [Publishing signed releases](../guides/native-hosts.md#publishing-signed-releases)
for key creation, host provisioning and rotation.
Builds also bundle report workers
under `build/reports` and launch preparation under `build/launch`. Development
and test commands compile those workers automatically. Restart `npm run dev`
after changing agent or worker code, or run `npm run agent:package` to refresh