Installation
One command installs a single binary. There is no config file to write and no account to create — after installing, you can scan immediately.
Quick install
The installer detects your OS and architecture, downloads the release binary, verifies its checksum, and installs it to /usr/bin/hostveil:
curl -fsSL https://hostveil.seolcu.com/install.sh | bash
Run the same command any time to update to the latest release. Then verify:
hostveil versionHostveil audits Linux hosts. Prebuilt binaries are published for Linux and macOS on amd64 and arm64, and the macOS build runs — but every detection rule in it is about Linux, so on a Mac most domains report N/A and the score is drawn from the two that do not. See Running it on macOS before you read a number it gives you there.
What the installer does
- Detects your OS (
linux/darwin) and architecture (amd64/arm64). - Downloads the release tarball and
hostveil-checksums.txt, then verifies the SHA-256 checksum. On a mismatch it aborts. - Installs the binary to
/usr/bin/hostveilwithsudo(mode 0755) and runshostveil --versionas a sanity check. - Offers to install Trivy for optional image CVE scanning. Declining never blocks the Hostveil install.
Installer options
| Option | Effect |
|---|---|
--version vX.Y.Z | Install a specific release instead of the latest. |
--no-trivy | Skip the optional Trivy prompt entirely. |
--yes / -y | Run non-interactively (accept prompts). |
Pass options through the pipe with bash -s --, for example:
curl -fsSL https://hostveil.seolcu.com/install.sh | bash -s -- --no-trivyElevation is automatic
The SSH and firewall checks read root-owned files (such as sshd_config), and applying fixes writes to protected paths. So hostveil re-runs itself under sudo automatically — you'll see the same sudo password prompt as sudo hostveil, and after authenticating it continues in the same terminal. version and help never prompt. To run unprivileged (scripts/CI), set HOSTVEIL_NO_SUDO=1; the root-owned domains are then skipped with a clear message and the score is renormalized so you are not handed a misleadingly perfect result.
Optional tools
Every domain is skipped cleanly if its tooling is absent. Add these when you want the extra coverage:
| Tool | Unlocks | Notes |
|---|---|---|
| Docker | The Docker / Compose audit | Hostveil reads your Compose files to audit services. |
| Trivy | Image CVE scanning | Used if present; the installer can set it up for you. |
| Ollama | AI explanations (explain --ai) | Local by default — nothing leaves your host. Not required: set HOSTVEIL_AI_PROVIDER=anthropic or openai to use an external API instead, useful on a host too small to run a local model. See AI explanations. |
Debian and RPM packages
Every release also ships .deb and .rpm packages, for people who would rather not pipe a script into a shell — a reasonable preference, especially for a security tool. Download the one matching your architecture from the latest release and install it with your package manager:
sudo apt install ./hostveil_<version>_linux_amd64.deb
# or
sudo dnf install ./hostveil-<version>.x86_64.rpmThe package installs the same single binary to the same path the installer uses, /usr/bin/hostveil, so the two are interchangeable — you can move from one to the other without ending up with two copies on your PATH. Docker and iproute2 are listed as recommended, never required: without them the container, CVE, and exposed-service domains report N/A rather than Hostveil failing to run.
There is no service to enable and no config file to edit. Removing the package leaves /var/lib/hostveil in place, for the same reason --uninstall does: those checkpoints are the backups of every file Hostveil has edited.
Packages are Linux-only.
Verifying what you downloaded
You are being asked to pipe a script into a shell and then run a tool as root. Here is what you can check before you do.
The installer already verifies the checksum of the archive it fetches against the release’s own hostveil-checksums.txt, and discards anything that does not match. That proves the bytes arrived intact. It does not prove who produced them — a checksum file published beside a tampered archive matches it perfectly.
Every release archive carries a signed build provenance attestation, which does prove that: the archive was built by this repository’s release workflow, from a named commit, at a named tag. Nothing running on a maintainer’s laptop can produce one.
gh attestation verify hostveil-linux-amd64.tar.gz --repo seolcu/hostveilhostveil update runs that check for you where the GitHub CLI is present. A provenance check that fails stops the update; one that cannot run because gh is not installed is a note rather than an error, because a checksum still proves the bytes are intact and it would be dishonest to imply otherwise.
Each archive also ships an SBOM (.sbom.json) listing everything that went into the binary, so you can answer “does this contain the library in today’s advisory” without building it yourself.
Running it on macOS
The macOS build is a real build — the installer takes it, it runs, and it produces a report. It is published because Hostveil is often driven from a laptop and because a build that is not published is a build nobody notices breaking. What it is not is a macOS auditor: there is no Darwin-specific rule anywhere in the tool.
On a Mac with no Docker, ten of the twelve domains report N/A. Seven find nothing to look at on their own — no /proc/sys, no systemd, no apt or dnf, no ss — and three more are excluded deliberately, because on macOS they would have answered a question they had not asked:
| Domain | On macOS |
|---|---|
| Host firewall | Excluded. Hostveil probes ufw, firewalld, nftables and iptables. macOS has none of them and uses pf instead, so “none of my probes found anything” would have been reported as firewall.inactive — a top-severity finding about a firewall Hostveil never looked for. |
| Account hygiene | Excluded. macOS ships an /etc/passwd, but the account database is Open Directory and that file does not describe the host. The /etc/shadow half cannot run at all, and the advice it would print — re-run with sudo — could never help, because the file is absent rather than unreadable. |
| AI agent runtimes | Excluded. It finds home directories through the same /etc/passwd, keeping the Linux UID range. macOS accounts start at 501, so it would have found only /var/root and reported “no agent runtime” about a host whose /Users it never opened. |
Two domains do run. SSH reads /etc/ssh/sshd_config, which macOS ships whether or not Remote Login is on, and its findings are about OpenSSH rather than about Linux — PasswordAuthentication means the same thing on Darwin. File permissions stats the files it recognises and skips the rest. On stock macOS both are usually clean.
The SSH domain is not read-only theatre. hostveil fix ssh.passwordauth on a Mac backs up and rewrites /etc/ssh/sshd_config, exactly as it would on a server, and it is reversible from hostveil history the same way. That is correct behaviour and worth knowing before you run it on a laptop.
And the score is a number, not N/A: two domains ran, so there is something to average. It is an average over 19 of the 100 points of weight, and it says nothing about the ten domains that did not run. Read the axis breakdown, not the headline. Nothing about pf, the application firewall, Homebrew’s update state, launchd services, or System Integrity Protection is examined by any part of hostveil.
Upgrading and uninstalling
Hostveil does both itself, and the reason it does rather than telling you to re-run the installer is that it knows how this binary got here.
hostveil update # --check to ask without changing anything
hostveil uninstallupdate works out the origin — the install script, a .deb, an .rpm, or go install — and updates it the same way. Re-running the install script over a packaged install replaces a file dpkg or rpm still believes it owns, which is the state this command exists to avoid. The download is checked against the release’s checksums and, where the GitHub CLI is present, against the signed build provenance. If Hostveil cannot tell how the binary was installed it does nothing and says so. See the CLI reference for the full origin table.
Uninstalling removes /usr/bin/hostveil and prints where the state directory is — without deleting it. Those checkpoints are the backups of every file Hostveil has edited on this host, and removing the tool is not a decision to give up the ability to undo its fixes. The command to delete them is printed if you want it. Trivy is left alone too: it is a general-purpose scanner that may predate Hostveil or be used by something else.
Build from source
With a recent Go toolchain installed:
git clone https://github.com/seolcu/hostveil
cd hostveil
go build ./cmd/hostveil
go test ./...See Contributing for the full development setup, including the reproducible demo VM.