SenHub Agent 0.5.0¶
2026-07-06 · security hardening, secret store, signed Windows MSI
Three lines of work land together. An audit-360 hardening batch
closes a set of findings across the config connectivity test (SSRF
guard, agent-key auth, bounded bodies and timeouts), config redaction
before logging, and several probe/output correctness gaps. A new
secret store keeps passwords and tokens out of the config: a
${secret:} resolver backed by OS-native storage (age / systemd-creds /
DPAPI), an agent secret command family, and config_version 3 that
auto-seals inline secrets on first boot. The Windows MSI becomes a
guided, code-signed installer with unattended provisioning, adoption of
an existing agent, and MSI-managed auto-update.
Action may be required
Inline secrets are auto-sealed on first boot. The first time
0.5.0 starts, any inline plaintext secret still present in your
configuration is moved into the OS-native secret store, replaced by
a ${secret:...} reference, and the file is stamped
config_version: 3. This is automatic and non-fatal (a sealing
fault restores its own backups and the agent keeps running), but it
rewrites the config on disk. A secret-free config stays at
version 2 and is untouched.
Two consequences to plan for:
- Do not downgrade under a sealed config. An older agent
(0.4.x and earlier, maximum supported
config_version2) refuses a version 3 config rather than pass an unresolved${secret:}literal to a probe. Upgrade every agent before distributing a sealed config. - Windows MSI installs now auto-update by applying a new MSI, not by swapping the binary in place. Fleets driven by the MSI should expect the installer-based update path. See the Windows MSI deployment guide.
New¶
- New secret A secret store resolves
${secret:NAME}references at config load time so passwords and tokens never sit in plaintext inagent.yaml,probes.d/*.yamlorstrategies.d/*.yaml. A missing required reference aborts boot with the offending name (never its value); the store is only created on disk when a${secret:}reference actually exists. (#606) - New secret OS-native backends selected automatically per platform:
age-keyfileon Linux/macOS,systemd-credsas the hardened systemd opt-in, anddpapion Windows. Backends initialize lazily and store their data next to the agent configuration. (#606) - New CLI
agent secret set/get/list/rm/status(plusmigrateand, on systemd,wire-unit) manage the store. A secret VALUE is never accepted on the command line —setreads from a hidden prompt, stdin, or--from-file. (#606) - New config
config_version 3(Secret References): on boot the agent seals inline plaintext secrets into the store and rewrites them as${secret:...}. The bump to 3 happens only when a secret is actually sealed; a secret-free version 2 config stays version 2 and loads unchanged. (#606) - New config The agent authentication key can be sealed into the store, with
agent key showto reveal it behind the privilege gate. (#606) - New packaging A guided Windows MSI installer (WiX 5.0.2) with license, tags and OTLP endpoint properties, and
config initfor unattended installs that seeds and provisions the configuration (including an OTLP push endpoint) without an interactive step. (#607) - New packaging Code-signed MSI, executable and PowerShell payload, signed with an HSM-backed Certum certificate via jsign. (#607)
- New packaging The installer detects an existing agent and supports ADOPT migration, taking over an already-installed instance instead of failing or duplicating it. (#607)
- New Veeam The Veeam job running-duration metric is now mapped (OTel and PRTG). (#602)
Improved¶
- Improved auto-update On MSI-managed Windows installs, auto-update applies a new MSI rather than swapping the binary, so the packaged install stays consistent with its installer state. (#607)
- Improved CLI Destructive actions (uninstall,
secret rm, license remove) now confirm with a unified[y/N]prompt; a bypass flag skips it for unattended runs (--yesfor uninstall andsecret rm,--forcefor license remove). (#609) - Improved CLI
--helpsurfaces thesecret,key,db-monitoringandconfig initcommands. (#609)
Fixed¶
- Security HTTP The config connectivity test (
validate/preview/test) now blocks link-local and metadata targets (SSRF guard), requires agent-key auth, bounds the request body size, and bounds outbound HTTP client timeouts. (#609) - Security config Resolved config parameters are redacted before logging, so secrets substituted into the config never reach the logs. (#609)
- Security OTLP The OTLP strategy fails fast on a blank auth token instead of silently sending unauthenticated. (#609)
- Security packaging The MSI masks
LICENSE_KEYin the install log and stages the update MSI in a private per-run directory instead of shared temp (TOCTOU hardening). (#607, #609) - Security ci GitHub Actions are pinned to commit SHA. (#609)
- Fixed otlp_receiver Re-exported metrics preserve their instrument type and unit, instead of being flattened on the way back out. (#609)
- Fixed senhub A permanent
4xxresponse now drops the payload instead of retrying it forever; transient auth failures (401/403) are retried rather than dropped, so an intake auth blip does not lose data. (#609, #613) - Fixed linux_logs Death of the
journalctlsubprocess is detected and the reader is respawned with a bounded backoff, so log collection resumes without an agent restart. (#609, #613) - Fixed logicaldisk All real filesystems are collected via a blocklist, instead of an allowlist that dropped legitimate mounts. (#609)
- Fixed entity Locally-monitored probe targets are anchored to their host with
runs_on, so a local target no longer surfaces as an isolated entity. (#601) - Fixed CLI
db-monitoringno longer requires administrator on Windows. (#609) - Fixed CLI
agent update --helpno longer tries to install a release named--help. (#609) - Fixed auto-update The release list is revalidated with no-cache, so a freshly published stable is seen at once. (#599)
Changed¶
- Changed CLI Decorative emoji are removed from CLI output, fatal errors print a plain
Errorline, and diagnostic errors and warnings are routed to stderr — friendlier for scripts and log capture. (#609) - Breaking Prometheus OTLP-ingested cumulative counters are now exported as counters, so the Prometheus endpoint appends the OpenMetrics
_totalsuffix (for examplehttp_server_requestsbecomeshttp_server_requests_total). This is the correct OpenMetrics naming, but scrape-visible series names change on upgrade — update any dashboards or alerts that match the old names. (#613) - Changed secret The secret store returns stored values exactly as written (no whitespace trimming), so a secret with meaningful leading or trailing bytes round-trips unchanged. (#613)
Internal¶
- Internal license The license field is edited at the YAML node level rather than by re-marshalling the whole config, preserving the rest of the file untouched. (#609)
- Internal config Generated config comments trimmed; the config-check version derives from
CurrentConfigVersion; the show load path records the config directory. (#609) - Internal packaging A local Certum signing helper (
sign-release-msi.sh) and an updated MSI guide document the release-time signing flow; the MSI CI workflow is dev/test-only (manual dispatch). (#607, #610)