Service deployment examples
These examples configure one service process with SQLite on a local filesystem. Caddy terminates HTTPS; the service accepts only loopback listener addresses and ignores forwarded headers. For checksum verification, package layout, supported binary platform, upgrade boundaries, and removal, start with the Linux release installation guide.
The installable examples remain canonical files in the repository rather than book chapters:
- server service
- hourly backup service and timer
- daily maintenance service and timer
- service environment example
- Caddy configuration example
-
Verify and extract the reviewed release package. Install its
agent-coordinator-serverandagent-coordinatorbinaries under/usr/local/bin. Assets and migrations are embedded in the server. -
Create an unprivileged
agent-coordinatorsystem account and group, a/var/lib/agent-coordinatordirectory owned by that account with mode 0700, and/etc/agent-coordinatorowned by root. -
Copy
service.env.exampleto/etc/agent-coordinator/service.env, set the real HTTPS origin, and protect it with mode 0640 and groupagent-coordinator. -
As the service account, initialize the administrator before starting the service (the password is entered through a hidden prompt):
sudo -u agent-coordinator /usr/local/bin/agent-coordinator-server \ --database /var/lib/agent-coordinator/coordinator.sqlite3 \ --public-origin https://coordinator.example.com \ init-admin --username adminAutomation may add
--password-stdinand supply the password through a protected pipe. There is deliberately no password command-line argument. Initialization succeeds only on an empty installation; it is not an account recovery command. Use My account for password changes, or the audited hostrecover-operator-passwordcommand described in the operator guide for account recovery. -
Install
agent-coordinator.serviceunder/etc/systemd/system, reload systemd, and enable/start the service. Install Caddy with the matching public hostname fromCaddyfile.example. Permit public HTTPS to Caddy and keep port 8080 private. Configure DNS and normal certificate issuance for that hostname. Validate the actual configuration withcaddy validate --config /etc/caddy/Caddyfilebefore reloading Caddy; see its request-body size limit documentation. -
Open the HTTPS site, sign in, and issue a named agent credential. The token is displayed once. If that response is lost, retry the same request/key to recover its identity, then rotate that credential under Access to issue a replacement for the same agent principal. A token is never replayed.
-
Create the separate backup repository and install the hourly backup units:
sudo install -d -o agent-coordinator -g agent-coordinator -m 0700 \ /var/lib/agent-coordinator-backups sudo install -o root -g root -m 0644 \ deploy/agent-coordinator-backup.service \ deploy/agent-coordinator-backup.timer \ /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl start agent-coordinator-backup.serviceConfirm that the first oneshot succeeded and verify its reported snapshot. Timer activation alone is not backup evidence. Configure an alert for a failed backup unit and stale verified-snapshot age. See the backup and restore guide for retention, advisory-locked off-server copies, restore authority invalidation, and the required recovery exercise.
Enable the persistent schedule only after the first snapshot passes verification:
sudo systemctl enable --now agent-coordinator-backup.timer
Install the daily maintenance timer for bounded replay/health payload compaction. Permanent task and lesson history remains stored. Follow the clock recovery guide if the service reports a clock reconciliation pause.
For local development only, use
--public-origin http://127.0.0.1:8080 --allow-insecure-loopback. The explicit
opt-in permits a non-Secure development cookie solely for a loopback origin.
HTTPS uses a Secure, HttpOnly, SameSite=Strict cookie with a 12-hour absolute
lifetime and a __Host- prefix. Browser writes require the exact configured
Origin, X-CSRF-Token, and Idempotency-Key headers. Login requires the origin
but has no idempotency receipt because it creates a fresh browser session.
Password hashes use Argon2id with 19 MiB memory, two iterations, and one lane, matching the OWASP password-storage minimum reviewed on 2026-09-09. Password checks run away from async workers, with at most two concurrent checks. Sign-in is limited to five attempts per username and 30 total attempts per minute, using a bounded in-process table and monotonic time. Restart resets that limiter; use proxy/network controls for internet-scale traffic. The service does not trust client-supplied forwarding headers to bypass its global limit.
The server stores only credential/session verifiers and redacts issued tokens from mutation receipts and events. Do not enable HTTP access logs that record headers, bodies, or query strings. Protect the database, its WAL files, artifacts, and every backup snapshot as credentials. Database initialization uses mode 0600; systemd uses umask 0077. The installed backup repository is local protection only. Do not claim host-loss protection until a complete destination copy has passed destination-side verification, and do not claim the one-hour restore target until the documented recovery exercise has measured it end to end.