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.
What’s new in v1.2.0
- An importable package
- All of Salus’s code moved from
internalinto an importablepkgpackage, andmain.gonow 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
- All of Salus’s code moved from
- 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 showslatestin itsdocker pullcommand gh attestation verify oci://ghcr.io/jabbott-iii/salus:1.2.0still finds and checks it
- The container image’s signed build provenance is now stored with GitHub instead of being pushed to the registry as an extra
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,memoryandcpu-load, each with its own WARN and FAIL thresholds - Containers and clusters:
docker-status,kubernetes-statusandkubernetes-pods, including unhealthy or restarting containers, node pressure and crash-looping pods - Services and time:
service-uptime,systemd-failedandtime-sync - Certificates:
cert-expiryfor PEM and DER files, with a configurable warning window - Configuration:
misconfig, with a stable rule ID on every finding, such assshd-root-login
- System resources:
- Monitoring and CI output
--formatselectstext,json,nagios,prometheusorjunit- Exit codes
0to3follow 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
--outputreplaces the report file atomically
- Run history
- Every
check runis saved to a local SQLite database salus jobs diff,salus jobs statsandsalus jobs prunecompare runs, spot flapping checks and keep the database small
- Every
- Built for unattended runs
--check-timeoutand--run-timeoutturn 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
--serviceintosystemctl, 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
- 10 security findings recorded, each with a fix shipped, including option injection through
- Testing
- CI runs
go vet, golangci-lint and the full test suite on Linux, macOS and Windows, then smoke-tests the built binary
- CI runs
- 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.txtand a signed SLSA build provenance attestation - The multi-arch image (
linux/amd64,linux/arm64) atghcr.io/jabbott-iii/salusruns as an unprivileged user (UID10001) - 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!