sfetch

command module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 1, 2026 License: MIT Imports: 30 Imported by: 0

README

sfetch

Secure, verifiable, zero-trust downloader for the uncertain world

The one-liner

sfetch is the curl | sh you can actually trust in 2026.

A tiny (~3 MB), statically-linked Go binary that downloads release artifacts from GitHub and verifies signatures and checksums automatically - using minisign, PGP, or raw ed25519.

No runtime dependencies. No package manager required. Works in CI, Docker, and air-gapped environments. See CI/CD Usage Guide for container and pipeline examples.

Why sfetch exists

Every modern engineering org signs their releases now.
Yet we still ship 15-line bash bootstrap scripts that do manual curl → sha256sum → maybe cosign verify.

sfetch is the missing 1% that deletes those scripts forever.

Security & Verification

See docs/security.md.

Asset Discovery

Auto-selects via heuristics (docs/pattern-matching.md) and classifies assets (archives vs raw scripts/binaries vs package-like). Raw files skip extraction; scripts/binaries are chmod'd on macOS/Linux. Use --asset-match for glob/substring selection or --asset-regex for advanced regex.

Install permissions
  • Archives (.tar.gz, .zip, etc.): Permissions from the archive are preserved. Executables packaged with 0755 remain executable after extraction.
  • Raw scripts/binaries (e.g., install.sh, kubectl): Automatically set to 0755 on macOS/Linux to ensure executability.
  • Cross-device installs: When --dest-dir is on a different filesystem than the temp directory (common in containers), sfetch falls back to copy and preserves the source permissions.
Signature verification

Minisign - pure-Go, no external dependencies

  • --minisign-key <pubkey.pub> - path to public key file
  • --minisign-key-url <url> - download key from URL
  • --minisign-key-asset <name> - fetch key from release assets
  • --require-minisign - fail if minisign verification unavailable
  • Auto-detects *.pub files from release assets when no key flags provided

PGP - requires gpg binary

  • --pgp-key-file <key.asc> - path to ASCII-armored public key
  • --pgp-key-url <url> - download key from URL
  • --pgp-key-asset <name> - fetch key from release assets
  • Auto-detects *-signing-key.asc or *-release*.asc from release assets

Raw ed25519 - pure-Go (uncommon format)

  • --key <64-hex-bytes> for .sig or .sig.ed25519 files

See docs/key-handling.md for details. Run sfetch -helpextended for examples.

Verification assessment

sfetch computes a trust score (0–100) from the verification plan/results, and can optionally gate installs with --trust-minimum.

Design guide: docs/trust-rating-system.md.

Dry-run mode - see what verification is available before downloading:

sfetch --repo BurntSushi/ripgrep --latest --dry-run

Enforce a minimum trust score (useful in CI):

# Require at least medium trust
sfetch --repo 3leaps/sfetch --latest --trust-minimum 60 --dest-dir /tmp

Provenance records - structured JSON for audit trails and CI:

sfetch --repo 3leaps/sfetch --latest --dest-dir /tmp --provenance-file audit.json

Verify installed binary - print instructions to verify your sfetch installation:

sfetch --self-verify

Self-update - update sfetch to the latest verified release:

# Update if newer version is available (skips reinstall if already current)
sfetch --self-update --yes

# Force reinstall even if already at the target version
sfetch --self-update --self-update-force --yes

# Pin to a specific version (allows downgrades)
sfetch --self-update --tag v0.2.3 --yes

For machine-readable trust anchors:

sfetch --show-trust-anchors        # plain: minisign:<key>
sfetch --show-trust-anchors --json # JSON with pubkey and keyId

See docs/examples.md for comprehensive real-world examples.

Build, versioning & install

sfetch uses Semantic Versioning. See ADR-0001 for versioning history.

make build             # produces bin/sfetch_${GOOS}_${GOARCH}
make install           # installs to ~/.local/bin by default
INSTALL_BINDIR=~/bin make install  # override install location
  • Edit buildconfig.mk to change the canonical binary name (NAME) or default install destination once.
  • On Windows, make install targets %USERPROFILE%\bin; ensure that directory is present in PATH.
Bootstrap install
# Using curl
curl -sSfL https://github.com/3leaps/sfetch/releases/latest/download/install-sfetch.sh | bash

# Using wget
wget -qO- https://github.com/3leaps/sfetch/releases/latest/download/install-sfetch.sh | bash
Installer options

Pass arguments using bash -s --:

# Install to custom directory
curl -sSfL .../install-sfetch.sh | bash -s -- --dir ~/bin

# Install specific version
curl -sSfL .../install-sfetch.sh | bash -s -- --tag v0.2.0

# Dry run (download and verify, don't install)
curl -sSfL .../install-sfetch.sh | bash -s -- --dry-run

# Skip confirmation prompt
curl -sSfL .../install-sfetch.sh | bash -s -- --yes

# Allow checksum-only (NOT recommended; skips signature verification)
curl -sSfL .../install-sfetch.sh | bash -s -- --allow-checksum-only

The installer:

  • Detects platform (linux/darwin/windows, amd64/arm64)
  • Requires minisign verification by default using the embedded trust anchor
  • Optional GPG fallback with pinned fingerprint; checksum-only requires explicit --allow-checksum-only
Verify before piping to bash

For users who prefer to verify the installer before execution:

# Detect OS-appropriate SHA256 command (macOS uses shasum, Linux uses sha256sum)
if command -v sha256sum &>/dev/null; then
  SHA_CMD="sha256sum"
else
  SHA_CMD="shasum -a 256"
fi

# Download assets (curl)
curl -sSfL https://github.com/3leaps/sfetch/releases/latest/download/install-sfetch.sh -o install-sfetch.sh
curl -sSfL https://github.com/3leaps/sfetch/releases/latest/download/SHA256SUMS -o SHA256SUMS

# Download assets (wget alternative - use -O to overwrite existing files)
# wget -qO install-sfetch.sh https://github.com/3leaps/sfetch/releases/latest/download/install-sfetch.sh
# wget -qO SHA256SUMS https://github.com/3leaps/sfetch/releases/latest/download/SHA256SUMS

# Option A: Verify with minisign (recommended)
curl -sSfL https://github.com/3leaps/sfetch/releases/latest/download/SHA256SUMS.minisig -o SHA256SUMS.minisig
minisign -Vm SHA256SUMS -P RWTAoUJ007VE3h8tbHlBCyk2+y0nn7kyA4QP34LTzdtk8M6A2sryQtZC
$SHA_CMD -c SHA256SUMS --ignore-missing

# Option B: Verify with GPG (uses temp keyring)
curl -sSfL https://github.com/3leaps/sfetch/releases/latest/download/SHA256SUMS.asc -o SHA256SUMS.asc
curl -sSfL https://github.com/3leaps/sfetch/releases/latest/download/sfetch-release-signing-key.asc -o sfetch-release-signing-key.asc
GPG_TMPDIR=$(mktemp -d)
gpg --homedir "$GPG_TMPDIR" --import sfetch-release-signing-key.asc
gpg --homedir "$GPG_TMPDIR" --verify SHA256SUMS.asc SHA256SUMS
rm -rf "$GPG_TMPDIR"
$SHA_CMD -c SHA256SUMS --ignore-missing

# Run after verification
bash install-sfetch.sh
Manual signing workflow

CI uploads unsigned archives. Maintainers generate SHA256SUMS and SHA2-512SUMS locally, then sign them with minisign (primary) and optionally PGP:

export MINISIGN_KEY=/path/to/sfetch.key
export PGP_KEY_ID=security@fulmenhq.dev  # optional

RELEASE_TAG=v0.2.0 make release-download
RELEASE_TAG=v0.2.0 make release-checksums
RELEASE_TAG=v0.2.0 make release-sign
make release-export-minisign-key
make release-export-key                   # if using PGP
RELEASE_TAG=v0.2.0 make release-notes
RELEASE_TAG=v0.2.0 make release-upload

Set RELEASE_TAG to the tag you're publishing. The scripts in scripts/ can be used individually if you prefer manual control.

Quick examples
# Download with auto-detected verification (minisign or PGP key from release assets)
sfetch --repo 3leaps/sfetch --latest --dest-dir ~/.local/bin

# Download installer script (no extraction, auto-chmod)
sfetch --repo 3leaps/sfetch --latest --asset-match "install-sfetch.sh" --dest-dir /tmp

# Standalone binary with explicit override for ambiguous extensions
sfetch --repo owner/tool --latest --asset-type raw --dest-dir /usr/local/bin

# Match by glob/substring instead of regex
sfetch --repo jedisct1/minisign --latest --asset-match "*macos*.zip" --dest-dir /usr/local/bin

# Advanced: regex match remains available
sfetch --repo jedisct1/minisign --latest --asset-regex "minisign-.*-macos.zip$" --dest-dir /usr/local/bin

# Dry-run to assess what verification is available
sfetch --repo BurntSushi/ripgrep --latest --dry-run

# Explicit minisign key
sfetch --repo jedisct1/minisign --latest --minisign-key /path/to/key.pub --dest-dir /usr/local/bin

# PGP verification
sfetch --repo fulmenhq/goneat --latest --pgp-key-file fulmen-release.asc --dest-dir /usr/local/bin

# Pin to specific version
sfetch --repo fulmenhq/goneat --tag v0.3.14 --dest-dir /usr/local/bin

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
cli
pkg
update
Package update provides small, dependency-free helpers for deciding whether a self-update should proceed.
Package update provides small, dependency-free helpers for deciding whether a self-update should proceed.
cmd/generate-checksums command
Command generate-checksums writes checksum files for release artifacts using stdlib hashes.
Command generate-checksums writes checksum files for release artifacts using stdlib hashes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL