Installation
One binary, several ways in. The script is the default; the rest is for people who want to see what it does, or who cannot run it.
The installer
$ curl -fsSL https://kapsl.sh/install | sh
The script is POSIX sh, and it does five things in order:
- Detects the platform from
uname -s/uname -mand maps it to a target triple (the table below). - Resolves the version from
https://kapsl.sh/releases/latest— a plain-text file holding just the version string, deliberately not a JSON API: the script has nojq, and grepping JSON is the kind of parsing that breaks silently on a formatting change. - Downloads
kapsl-<version>-<target>.tar.gzand its.sha256fromhttps://kapsl.sh/releases/<version>/, withcurlorwget. - Verifies the checksum —
sha256sum -c, orshasum -a 256on macOS — and stops on a mismatch: the download "may be corrupted or tampered with". - Installs to
~/.local/bin(creating it if needed, thenchmod +xon the binary) and prints a PATH hint — the exactexportline — when the directory is not on your PATH.
Requires curl or wget, tar, and sha256sum/shasum. Environment overrides: KAPSL_VERSION to pin an exact version (do this in CI so a pipeline is reproducible), KAPSL_INSTALL_DIR to install elsewhere, KAPSL_BASE_URL to point at a mirror.
Manual install
The targets the script knows:
| Platform | Target |
|---|---|
| Linux, x86-64 | x86_64-unknown-linux-musl |
| Linux, arm64 | aarch64-unknown-linux-musl |
| macOS, Intel | x86_64-apple-darwin |
| macOS, Apple Silicon | aarch64-apple-darwin |
The same five steps, spelled out — the URL layout is the script's:
$ version=$(curl -fsSL https://kapsl.sh/releases/latest)
$ target=aarch64-apple-darwin
$ curl -fsSLO "https://kapsl.sh/releases/${version}/kapsl-${version}-${target}.tar.gz"
$ curl -fsSLO "https://kapsl.sh/releases/${version}/kapsl-${version}-${target}.tar.gz.sha256"
$ shasum -a 256 -c "kapsl-${version}-${target}.tar.gz.sha256"
$ mkdir -p ~/.local/bin
$ tar -xzf "kapsl-${version}-${target}.tar.gz" -C ~/.local/bin
Use sha256sum -c instead of shasum on Linux. The script installs the archive's kapsl binary straight into the directory.
Build from source
$ cargo build --release
$ cp target/release/kapsl ~/.local/bin/
A Rust toolchain is the only prerequisite.
Choosing the runtime
kapsl prefers Podman and falls back to Docker when podman is not installed. The full precedence, highest first:
--runtime <name>— one invocation.KAPSL_RUNTIME— inherited by every kapsl process this shell spawns; the only mechanism that also reaches tools which call kapsl from inside a container.[global] runtimein~/.config/kapsl/kapsl.toml.- Whatever engine is installed — podman preferred, docker when podman is absent.
$ kapsl --runtime podman [email protected] --version
Python 3.12.14
$ KAPSL_RUNTIME=podman kapsl [email protected] --version
Python 3.12.14Uninstall
List what is installed, reclaim the disk, then remove the binary, the shims, and the data:
$ kapsl --list
Installed shims (1):
jq
$ kapsl --clean all --dry-run
▍ ■ INFO 10 items · 15 MB to remove
▍ 12 MB cache/scanner ~/.cache/kapsl/scanner/attestations
▍ 2.9 MB cache/scanner ~/.cache/kapsl/scanner/scan-cache.json
▍ 61 KB cache/index ~/.cache/kapsl/index/catalog.json
…
▍ kapsl-env-* images, package caches and the vulnerability database (not enumerated under --dry-run)
▍ ■ INFO --dry-run: nothing removed
--clean takes a target — scratch, images, cache, all, decisions (comma-separated; the default is scratch,images, the two that cost nothing to recreate). It always prints the plan first; cache and all ask before acting, and --yes pre-answers. decisions is never part of all, on purpose: it is the human-decisions store — accepted CVE sets, trusted projects — small, precious, and yours.
Then:
$ rm ~/.local/bin/kapsl ~/.local/bin/jq # the binary, and each shim from --list
$ rm -rf ~/.local/share/kapsl ~/.cache/kapsl
~/.cache/kapsl is everything regenerable — environment images, the scanner's vulnerability database, the catalogue cache; ~/.local/share/kapsl is your recorded decisions. Removing both returns the machine to the state it was in before the install. If you created ~/.config/kapsl/kapsl.toml, remove it too — there is no default file, and the absence is a working configuration.