Salus // Maintenance

Salus v1.2.0 - Production Maintenance Phase

Salus v1.2.0 enters production maintenance with 12 environment checks, five monitoring output formats, run history, cross-platform resource checks, 10 fixed security findings and signed multi-arch releases.

By 4 min read

Salus v1.2.0 — Now in Production Maintenance

I am proud to announce that Salus has reached its production maintenance phase!

Salus is a Go CLI that checks a host’s disk, memory, CPU, Docker, Kubernetes, services, clock, certificates and common misconfigurations, then prints a concise PASS / WARN / FAIL summary with an exit code that reflects the worst result. With v1.2.0, the set of checks, the output formats and the exit codes are settled, every recorded security finding has a fix, and every release is built, signed and published automatically. From here on, the focus shifts from building new features to keeping Salus stable, secure and up to date.

It has been five weeks since v1.0.0 shipped on September 27, with four releases since then (v1.0.1, v1.0.2, v1.1.0 and v1.2.0). Here is what came together to get here.

Salus running an environment health check

What’s new in v1.2.0

  • An importable package
    • All of Salus’s code moved from internal into an importable pkg package, and main.go now only holds the build version and the command wiring
    • This lets Capsus, my toolbox that bundles every command-line tool I have built into one binary, run Salus as one of its commands
  • Cleaner container package page
    • The container image’s signed build provenance is now stored with GitHub instead of being pushed to the registry as an extra sha256-… tag, so the GitHub Packages page shows latest in its docker pull command
    • gh attestation verify oci://ghcr.io/jabbott-iii/salus:1.2.0 still finds and checks it

v1.2.0 doesn’t change any check, flag, output format or exit code, so it is a drop-in upgrade from v1.1.0.

Where Salus stands

  • 12 checks
    • System resources: disk-space, disk-inodes, memory and cpu-load, each with its own WARN and FAIL thresholds
    • Containers and clusters: docker-status, kubernetes-status and kubernetes-pods, including unhealthy or restarting containers, node pressure and crash-looping pods
    • Services and time: service-uptime, systemd-failed and time-sync
    • Certificates: cert-expiry for PEM and DER files, with a configurable warning window
    • Configuration: misconfig, with a stable rule ID on every finding, such as sshd-root-login
  • Monitoring and CI output
    • --format selects text, json, nagios, prometheus or junit
    • Exit codes 0 to 3 follow the Nagios plugin convention, so Salus works as a Nagios, Icinga or Zabbix plugin without a wrapper
    • Prometheus output is made for node_exporter’s textfile collector, and --output replaces the report file atomically
  • Run history
    • Every check run is saved to a local SQLite database
    • salus jobs diff, salus jobs stats and salus jobs prune compare runs, spot flapping checks and keep the database small
  • Built for unattended runs
    • --check-timeout and --run-timeout turn a hung check into a FAIL instead of a stuck run
    • Several Salus processes can share one database, and the report is written before the run is saved
  • Cross-platform
    • Disk, inode, memory, CPU load and uptime checks measure the host on Linux, macOS and Windows

Every check and flag is covered in the v1.1.0 release post and the README.

Production hardening

  • Security
    • 10 security findings recorded, each with a fix shipped, including option injection through --service into systemctl, a container that ran as root, a database created with default permissions, unsigned releases, and external tool output that reached the terminal and the database unfiltered
    • External commands are bounded by the timeouts, their output is capped, and on Linux and macOS Salus stops the processes it started when one times out
    • CodeQL, gosec and govulncheck run on every change and weekly
  • Testing
    • CI runs go vet, golangci-lint and the full test suite on Linux, macOS and Windows, then smoke-tests the built binary
  • Release & Supply Chain
    • Native binaries for Linux, macOS and Windows on x86-64 and ARM64
    • Linux binaries are statically linked, so they do not depend on the system’s C library
    • Every release file and the container image carry checksums.txt and a signed SLSA build provenance attestation
    • The multi-arch image (linux/amd64, linux/arm64) at ghcr.io/jabbott-iii/salus runs as an unprivileged user (UID 10001)
    • Third-party GitHub Actions are pinned by commit SHA and base images by digest, and Dependabot keeps them current

Upgrading

From v1.1.0, replace the binary or pull the new image; nothing else changes.

From v1.0.2 or older, read the README’s Upgrading from 1.0.2 first. A plain salus check run now runs more checks, docker-status and kubernetes-status are stricter, and misconfig messages start with a rule ID, so some hosts that passed before now report WARN. Choose checks with --only, or pass --fail-on fail to let WARN pass.

To verify a download before you run it:

gh attestation verify salus_linux_amd64.tar.gz --repo jabbott-iii/Salus \
  --signer-workflow jabbott-iii/Salus/.github/workflows/cd.yml \
  --source-ref refs/tags/v1.2.0

Roadmap

Salus is now in production maintenance. Going forward:

  • Bug fixes and security patches ship in the next release; only the latest release is supported
  • Dependencies and the Go toolchain are kept current
  • Stability comes first; new features are not the focus

Found a vulnerability? Please report it privately through the repository’s Security tab, as described in SECURITY.md.

Thank you for following along!