Skip to content

SenHub Agent 0.2.3

2026-06-12 · security & resilience release

The security wave: every audit-flagged hardening lands at once. Self-updates are signature-verified (minisign, fail-closed), all network listeners default to loopback with explicit opt-in for remote access, the OTLP receiver gains token auth, CIDR allow-lists and rate limiting, snmp_poll speaks SNMPv3, and a long series of resilience fixes (bounded push buffers, atomic config reads, goroutine-leak class elimination, stale-series eviction) hardens long-running fleets.

Action may be required

Network listeners now bind 127.0.0.1 by default. Configs generated by agent install always set bind_address explicitly and are not affected. Hand-written configs that relied on the old bind-all default while being polled remotely must add an explicit bind_address. See the Changed section below.

New

  • New security Self-updates are now signature-verified: the agent checks a detached minisign signature over each release archive against a public key embedded at build time, and refuses unsigned or tampered artifacts (fail-closed; rejections surface as senhub.agent.update.rejected). (#266)
  • New security The OTLP receiver gains optional ingress protections: bearer_token auth (HTTP header or gRPC metadata), allowed_cidrs source allow-list and a rate_limit_rps token-bucket limiter — recommended whenever the receiver is opened beyond loopback. (#278)
  • New SNMP snmp_poll supports SNMPv3 (USM auth + privacy, security level derived from the configured protocols). (#156)
  • New SNMP snmp_poll gains mib_paths: a custom mapping may omit metric and have its name resolved from operator-supplied MIB files at startup. (#291)

Fixed

  • Fixed OTLP Stale series eviction (staleness_ttl, default 10m) — series whose probe was removed or denied no longer re-export forever with fresh timestamps from the persisted store (zombie metrics seen twice in production recettes). (#308)
  • Fixed topology A transient sweep failure no longer deletes the device tree in the consumer; sources are unregistered on probe shutdown; unchanged entity heartbeats are suppressed between refreshes. (#272)
  • Fixed SNMP senhub.snmp.up now reflects whether the device answered, not whether a UDP socket opened — a powered-off switch finally reports down. (#156)
  • Fixed security SNMPv3 passphrases and community strings are masked in logs. (#156)
  • Fixed security agent config show masks secrets by default; cleartext output now requires the explicit --resolved flag. (#279)
  • Fixed security agent install on Linux now writes the hardened systemd unit the packages ship — daemon runs as the dedicated senhub user (created at install) with all capabilities dropped, instead of an implicit root unit. install --user root keeps the legacy behavior; existing units are never rewritten on upgrade. (#280)
  • Fixed security The Windows administrator check uses the process token elevation API instead of probing \\.\PHYSICALDRIVE0, which broke on hosts without that device. (#280)
  • Fixed PRTG The PRTG push closes its HTTP response — it leaked one connection per sync cycle. (#277)
  • Fixed checks icmp_check defaults to privileged raw sockets on Linux when running as root — unprivileged datagram ICMP is disabled by default on Ubuntu/Debian (ping_group_range) and silently reported every target down; the permission error now carries an actionable hint. (#357)

Changed

  • Changed security All network listeners now default to loopback (127.0.0.1) instead of all interfaces: the HTTP API (bind_address), the OTLP receiver probe (address), the SNMP trap receiver (bind_address) and the syslog probe — whose bind address was previously hardcoded to 0.0.0.0 and is now configurable (bind_address). Accepting remote senders/pollers requires an explicit opt-in, and binding all interfaces logs a startup warning. Action required only for hand-written configs that omitted the bind parameter while relying on remote access — add bind_address: "0.0.0.0" (or a specific interface IP) to the relevant section; configs generated by agent install always wrote it explicitly. (#278)
  • Changed outputs The never-implemented Zabbix HTTP endpoint (always 501) is removed; endpoints: [zabbix] now fails fast at startup. The Zabbix integration is redesigned as a native active agent, deferred (#169).

Changed (metric names)

The OTel names of eight Windows/hardware rate metrics carried a per_second suffix in the NAME, which the Prometheus-compatibility layers then doubled with the unit-derived suffix (senhub_system_disk_io_per_second_bytes_per_second through an OTel collector). The unit now drives the suffix alone; the resulting Prometheus names are the ones the metrics reference always documented.

Before (OTel name) After (OTel name) Prometheus name (both ingestion paths)
senhub.system.cpu.dpcs_per_second senhub.system.cpu.dpcs senhub_system_cpu_dpcs_per_second
senhub.system.cpu.dpcs_queued_per_second senhub.system.cpu.dpcs_queued senhub_system_cpu_dpcs_queued_per_second
senhub.system.cpu.interrupts_per_second senhub.system.cpu.interrupts senhub_system_cpu_interrupts_per_second
senhub.system.paging.faults_per_second senhub.system.paging.faults senhub_system_paging_faults_per_second
senhub.system.paging.operations_per_second senhub.system.paging.operations senhub_system_paging_operations_per_second
senhub.system.disk.operations_per_second senhub.system.disk.operations senhub_system_disk_operations_per_second
senhub.system.disk.io_per_second senhub.system.disk.io senhub_system_disk_io_bytes_per_second
senhub.hardware.physical_disk.link_speed_bits_per_second senhub.hardware.physical_disk.link_speed senhub_hardware_physical_disk_link_speed_bits_per_second

Internal

  • Internal Shared snmpcore package — one printability semantics, value rendering, version mapping and v3 USM tables consumed by both SNMP probes. (#291)