# Install anywhere

**The `whisper` CLI is the one binary that gives an agent a real, routable IPv6 identity — and it only earns that job if it's on every machine that runs one.**

Your laptop, your teammate's Windows box, the CI runner, the Alpine container in prod, the NixOS build server. Package-manager sprawl is where good tools go to die: one more `curl | sh` that isn't pinned, one more stale download, one more platform onboarding forgets. Whisper ships as a single **MIT-licensed, statically-linked Go binary** — no runtime dependency, no phone-home — published to every channel a developer or CI pipeline reaches for first, each one signed, each one ending in the same check: `whisper --version`.

This page is the exhaustive list. Pick the channel that matches where the binary needs to live; skip the rest.

## The fast path

```bash
curl -fsSL https://get.whisper.online | sh
whisper --version
```

`get.whisper.online` serves a plain, readable shell script — pipe it through `less` first if you want to read it before you run it, that's the point of Postel's Law applied to supply chain: we make it trivial to inspect, we never make you trust blindly.

```bash
curl -fsSL https://get.whisper.online -o install.sh   # read it
less install.sh
sh install.sh                                          # then run it
```

## Every channel, at a glance

| Channel | Command | Platforms | Status |
|---|---|---|---|
| [Homebrew](#homebrew) | `brew install whisper-sec/tap/whisper` | macOS, Linux | live |
| [Scoop](#scoop) | `scoop install whisper` | Windows | live |
| [apt](#apt-debianubuntu) | `apt install whisper` | Debian, Ubuntu | live |
| [dnf](#dnf-fedorarhel) | `dnf install whisper` | Fedora, RHEL | live |
| [apk](#apk-alpine) | `apk add whisper` | Alpine | live |
| [go install](#go-install--mise) | `go install github.com/whisper-sec/whisper-cli/cmd/whisper@latest` | anywhere Go 1.21+ runs | live |
| [mise](#go-install--mise) | `mise use -g "github:whisper-sec/whisper-cli[exe=whisper]"` | anywhere | live |
| [aqua](#aqua) | `aqua g -i whisper-sec/whisper-cli && aqua i` | anywhere | registry PR pending, works today by pointing aqua at the checked-in registry entry |
| [nixpkgs](#nix) | `nix profile install nixpkgs#whisper-cli` | NixOS, nix-darwin, any Nix | upstream PR pending; build locally today with the flake below |
| [Snap](#snap) | `snap install whisper-cli --classic` | Linux | Snap Store review pending |
| [MacPorts](#macports) | `port install whisper-cli` | macOS | Portfile authored, needs a maintainer to lint + submit |
| [AUR](#aur) | `yay -S whisper-cli-bin` | Arch, Manjaro | `PKGBUILD` ready, queued for the AUR |
| [Docker](#docker--ghcr) | `docker run --rm ghcr.io/whisper-sec/whisper --version` | anywhere with a container runtime | live |
| [GitHub Actions](#ci-github-actions) | `uses: whisper-sec/setup-whisper@v1` | CI | live |

Every one of these builds from the same tagged release in [`whisper-sec/whisper-cli`](https://github.com/whisper-sec/whisper-cli) — there is no channel-specific fork of the binary, so `whisper --version` returns the identical build hash no matter how you got it.

## Homebrew

macOS and Linux, our own tap (not homebrew-core, so no review lag on new releases):

```bash
brew install whisper-sec/tap/whisper
whisper --version
```

**Without Whisper**, this is the manual equivalent — download the darwin-arm64 asset and its checksum straight from GitHub Releases and verify by hand:

```bash
curl -fsSLO https://github.com/whisper-sec/whisper-cli/releases/latest/download/whisper-darwin-arm64
curl -fsSLO https://github.com/whisper-sec/whisper-cli/releases/latest/download/checksums.txt
grep whisper-darwin-arm64 checksums.txt | sha256sum -c -
chmod +x whisper-darwin-arm64 && ./whisper-darwin-arm64 --version
```

The Homebrew formula pins that same per-arch sha256 in the tap, so `brew install` does the `sha256sum -c` for you on every install — that's what a formula bump *is*.

## Scoop

Windows, our own bucket:

```powershell
scoop bucket add whisper https://github.com/whisper-sec/scoop-bucket
scoop install whisper
whisper --version
```

**Without Whisper**, PowerShell's own hash check against the published `checksums.txt`:

```powershell
Invoke-WebRequest https://github.com/whisper-sec/whisper-cli/releases/latest/download/whisper-windows-amd64.exe -OutFile whisper.exe
Invoke-WebRequest https://github.com/whisper-sec/whisper-cli/releases/latest/download/checksums.txt -OutFile checksums.txt
Get-FileHash whisper.exe -Algorithm SHA256
Select-String whisper-windows-amd64.exe checksums.txt   # compare by eye, or script it
```

## apt (Debian/Ubuntu)

A self-hosted repo on our own address space (`AS219419`), signed with a dedicated RSA-4096 key (fingerprint `7570D759316F7C1F`) kept separate from the binary-release signing key:

```bash
curl -fsSL https://get.whisper.online/whisper.gpg | sudo tee /usr/share/keyrings/whisper.asc >/dev/null
echo "deb [signed-by=/usr/share/keyrings/whisper.asc] https://get.whisper.online/deb stable main" \
  | sudo tee /etc/apt/sources.list.d/whisper.list
sudo apt update && sudo apt install whisper
whisper --version
```

**Verify the key yourself before you trust it** (stock `gpg`, no Whisper software involved):

```bash
curl -fsSL https://get.whisper.online/whisper.gpg | gpg --show-keys --with-fingerprint --dry-run
# pub   rsa4096 ...  7570 D759 316F 7C1F ...
```

`apt` then does its normal `Release`/`InRelease` signature check against that key on every `apt update` — the same mechanism that protects every other repo on your system, nothing bespoke.

## dnf (Fedora/RHEL)

```bash
sudo tee /etc/yum.repos.d/whisper.repo >/dev/null <<'EOF'
[whisper]
name=Whisper
baseurl=https://get.whisper.online/rpm
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://get.whisper.online/whisper.gpg
EOF
sudo dnf install whisper
whisper --version
```

`dnf` checks both the package signature and the repo metadata (`repomd.xml.asc`) against the same RSA key as apt — one key, two package formats.

## apk (Alpine)

Alpine's `APKINDEX` format needs its own `abuild`-style RSA key (a different key from the apt/dnf one, by Alpine convention):

```bash
wget -qO /etc/apk/keys/whisper-apk.rsa.pub https://get.whisper.online/apk/whisper-apk.rsa.pub
echo "https://get.whisper.online/apk" | sudo tee -a /etc/apk/repositories
sudo apk add whisper
whisper --version
```

This is the one that matters most for the container-image case — a `FROM alpine:3.20` build stage that needs `whisper` baked in without pulling in Go or curl-piping a script into a Dockerfile.

## go install / mise

Straight from source, no binary trust decision at all beyond the Go module checksum database:

```bash
go install github.com/whisper-sec/whisper-cli/cmd/whisper@latest
whisper --version
```

```bash
mise use -g "github:whisper-sec/whisper-cli[exe=whisper]"
whisper --version
```

`go install` verifies the download against the checksum database at `sum.golang.org` automatically (`GOSUMDB`, unless you've explicitly opted out) — the module proxy's transparency log is doing the same job GPG does for the other channels, just built into the toolchain.

## aqua

The [aqua-registry](https://github.com/aquaproj/aqua-registry) entry resolves `{{.Version}}` against GitHub Releases, so once merged upstream a new tag needs no registry change:

```bash
aqua g -i whisper-sec/whisper-cli
aqua i
whisper --version
```

## Nix

```nix
# flake.nix or shell.nix
{ inputs.whisper.url = "github:whisper-sec/whisper-cli"; }
```

```bash
nix build github:whisper-sec/whisper-cli
./result/bin/whisper --version
```

The `buildGoModule` derivation pins both the source hash and the Go `vendorHash` — Nix will refuse to build if either drifts from what's declared, which is a stronger guarantee than a checksum file you have to remember to check.

## Snap

```bash
sudo snap install whisper-cli --classic
whisper --version
```

`--classic` confinement is required because `whisper connect` runs a local egress proxy — it binds a loopback socket and opens outbound connections on arbitrary ports — which strict confinement's network interfaces don't permit.

## MacPorts

```bash
sudo port install whisper-cli
whisper --version
```

## AUR

```bash
yay -S whisper-cli-bin          # or: paru, or a manual makepkg
whisper --version
```

The `-bin` package installs the prebuilt, signed release asset directly (no local Go toolchain needed); a source-build `whisper-cli` variant is the fallback for anyone who prefers to compile.

## Docker / GHCR

```bash
docker run --rm ghcr.io/whisper-sec/whisper --version
docker run --rm -e WHISPER_API_KEY ghcr.io/whisper-sec/whisper agent create --name shipping-bot
```

Multi-arch (`linux/amd64`, `linux/arm64`) — the same image works on a laptop and on Graviton CI runners without a tag change.

## CI: GitHub Actions

```yaml
- uses: whisper-sec/setup-whisper@v1
  with:
    version: latest
- run: whisper --version
```

Add `api-key: ${{ secrets.WHISPER_API_KEY }}` to the same step to have it export `WHISPER_API_KEY` for the rest of the job — every job step after that can `whisper agent create` / `whisper connect` without touching a config file. Other CI systems get the same result with any channel above (`apt`/`apk` in a container step, `go install` in a build image).

## Why every channel matters: the payoff is identical everywhere

Whichever way you installed it, the CLI does the same thing: prove an agent's identity against records anyone can already query with stock tools, just in one command instead of three.

These commands resolve against our live public demo agent, **scout** — copy-paste them as-is and they return real answers.

**With stock tools** — no `whisper` binary anywhere on the machine:

```bash
dig +short -x 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478
# -> ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online.
kdig +dnssec TLSA _443._tcp.ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online
# 3 1 1 9EC1EF18A1F15E54...201940F28C422BB47D — usage 3 (DANE-EE), selector 1 (SPKI), matching 1 (SHA-256)
openssl s_client -connect [2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478]:443 -servername ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online < /dev/null
```

**With Whisper**, once it's on your `$PATH` from any channel above:

```bash
whisper verify 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 --trustless
# chains PTR -> AAAA -> DNSSEC (RRSIG to the root) -> TLSA (RFC 6698) -> the live cert; prints PASS/FAIL
```

That's the whole point of getting the binary onto every machine: the verification is public and reproducible with `dig`/`kdig`/`openssl` alone — installing `whisper` doesn't add trust, it removes friction.

## Next

See [CLI reference](/docs/cli) for the full command surface, or [Every channel, every tier](/docs/integrations) for how the two-tier (keyless-verify / key-gated control) model shows up in SDKs, MCP, and CI beyond the raw binary.
