Skip to content

Releases: ziozzang/hftools

hftools v0.15.1

Choose a tag to compare

@ziozzang ziozzang released this 24 Jul 07:18

Security: signature-downgrade path that forged the signer label

Adversarial review of v0.15.0 found that binding the signer and time into a v2 signature did not by itself make the displayed identity trustworthy.

An attacker could take a v2 record, rewrite it as v1, strip metadata_signature, and change signer. The payload signature still verified — intentionally, so binaries predating v2 keep working — so verify-sig printed signature OK / signed by mallory@evil.example and exited 0, with only a trailing note on the same line that a reader could easily miss.

Fixed:

  • Labels not covered by a signature now render warning-first and quoted:
    UNVERIFIED signer "mallory@evil.example", time ... — not covered by the signature (pre-v2 record); treat as unproven
  • --require-signed-identity on verify, verify-batch, and verify-sig rejects such records outright (exit 1) instead of relying on the reader.
  • require_signed_identity: true in ~/.hftools/config.yaml enforces it everywhere without the flag.
  • Documented that pinning the key (--pubkey) or trusting it in the registry remains the strongest control, since it proves which key signed regardless of any label.
hftools verify --output ./repo --verify-sig --require-signed-identity

Cross-version compatibility is unchanged: a v0.14.1 binary still verifies signatures written by this release, and this release still verifies older ones.

Also reviewed and found safe, no changes needed: path traversal and symlink escape via manifest orphans with --prune (blocked by the existing path guard; symlinks are unlinked rather than followed), and --prune leaving user-added files untouched.

Upgrade with hftools update.

hftools v0.15.0

Choose a tag to compare

@ziozzang ziozzang released this 24 Jul 07:11

Signature attribution

verify --verify-sig and verify-batch --verify-sig now report who signed a repository and when, not just the key fingerprint:

  sig: OK 0f4095319cd38e03 (trusted: alice)
       signed by alice@corp.example at 2026-07-17T09:12:44Z

The signer label and signing time are now covered by a signature (schema v2). Previously they sat next to the signature as annotations that could be rewritten without breaking verification — displaying them as-is would have misattributed a download rather than proving anything.

Compatibility is preserved in both directions: v2 keeps the payload signature v1-compatible and adds a second signature over the signer/time binding, so older binaries verify new signatures and this release still verifies old ones. Signatures written by earlier versions are labeled as having unauthenticated signer/time instead of being presented as proof.

Set your label once with hftools key init --signer you@example.com.

Visible repository updates

A re-download now reports how the revision moved instead of only listing cached files:

update: a7121eefebf9 → 71034c5d8bde • 1 new • 1 changed • 8 unchanged • 1 removed upstream
  removed upstream: generation_config.json
note: 1 file(s) removed upstream are still on disk; re-run with --prune to delete them

Files deleted upstream were dropped from the manifest but silently left on disk. They are now reported, remembered so a later --prune can still find them, and deleted by --prune. Only files the download produced are ever removed, and --prune is inert under --filter, where an unselected file cannot be distinguished from a deleted one.

Zero external dependencies; static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.

hftools v0.14.1

Choose a tag to compare

@ziozzang ziozzang released this 23 Jul 13:33

ESC/q interrupt now works on macOS too

v0.14.0 made scan, verify, and verify-batch interruptible, but single-key ESC / q detection only covered Linux terminals. This adds a macOS cbreak watcher (using TIOCGETA/TIOCSETA), so ESC/q now stops long scans and verifies on both Linux and macOS terminals.

Ctrl+C still cancels on every platform, including Windows. As before, signals (ISIG) and output post-processing (OPOST) stay enabled, so the terminal is never left in a bad state — and it remains zero-dependency (build-tagged termios per platform).

Static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.

hftools v0.14.0

Choose a tag to compare

@ziozzang ziozzang released this 23 Jul 13:25

One-pass integrity + safety + provenance, and interruptible scans

verify and verify-batch no longer check only hashes. Fold the security scan and the signature check into the same pass so a single command proves a repository is intact, safe to load, and from a trusted signer:

hftools verify-batch --root ./models --scan --verify-sig
  • --scan runs the pickle/torch unsafe-import scan on each repository; a critical finding fails that repository.
  • --verify-sig verifies each repository's stored signature, auto-recognizing keys in your trusted registry. Pin explicitly with --pubkey <name|hex|PEM|file>.

Interruptible

Long scan, verify, and verify-batch runs can now be stopped cleanly:

  • Ctrl+C (SIGINT) on any platform — the operation checks for cancellation per file/repository and exits promptly.
  • ESC or q on a Linux terminal — a small cbreak watcher (zero-dependency, build-tagged; no-op elsewhere) catches the keypress. Signals stay enabled and output post-processing is preserved, so the terminal is never left in a bad state.

Zero external dependencies; static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.

hftools v0.13.0

Choose a tag to compare

@ziozzang ziozzang released this 23 Jul 13:00

Automatic signing on download and verify

Signing no longer needs a separate step. With auto_sign enabled, every download, dataset, space, batch, and verify / verify-batch signs the repository with your ~/.hftools identity the moment its .sha256 manifest is written — so a recipient can prove provenance right away.

  • config.yaml auto_sign is the persistent switch: hftools key init --auto-sign turns it on (creating the identity on first use).
  • --sign / --sign=false overrides the config default per run, on download/dataset/space/batch and verify/verify-batch.
  • verify signs only on a clean pass; watch signs once per cycle on its final verify.
hftools key init --signer you@example.com --auto-sign   # config.yaml auto_sign: true
hftools batch --list models.txt                          # each repo signed as it lands
hftools verify-batch --root ./repos                       # re-sign on a clean verify
hftools download owner/model --sign=false                 # opt out for one run

Recipients trust a signer once (hftools key trust <name> <pubkey>), then hftools verify-sig recognizes the signature and proves both integrity and provenance.

Zero external dependencies; static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.

hftools v0.12.0

Choose a tag to compare

@ziozzang ziozzang released this 23 Jul 12:47

Signing identity and trusted keys

Provenance signing now has a persistent per-user identity, so sign and verify-sig no longer require juggling PEM key paths, and a recipient can pin a signer by name.

  • ~/.hftools home store (override with $HFTOOLS_HOME): an ed25519 private key (signing.key, mode 0600), its public key (signing.pub), and a config.yaml holding the signer label and a trusted_keys registry. Still zero external dependencies — config.yaml uses a small built-in YAML reader.
  • sign with no --key uses the home identity, creating it (key + config.yaml) on first run, and defaults the signer label from config.
  • verify-sig auto-recognizes a signer whose key you have trusted (reports trusted key: NAME); --pubkey now also accepts a trusted name. It always prints the key's SHA-256 fingerprint, and when the key is unpinned/untrusted it suggests the key trust command.
  • New key command: init, show, export, trust, untrust, list, path.
# Signer — first sign creates ~/.hftools automatically:
hftools sign --output ./owner_model --signer you@example.com
hftools key export --out mykey.pem            # public key to distribute

# Recipient — trust the signer's key once, then verify:
hftools key trust alice mykey.pem
hftools verify-sig --output ./owner_model     # auto-recognizes the trusted key

Hashing proves a download is intact; a trusted signature proves who produced it — useful across an air gap.

Static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.

hftools v0.11.0

Choose a tag to compare

@ziozzang ziozzang released this 16 Jul 13:44

Publish to the Hub (write features)

This release absorbs the write side of huggingface-cli.

  • upload — publish files or a whole folder to a repository in a single commit. Large files are sent through Git LFS (basic or multipart); small files are embedded inline. Supports --path-in-repo, --message/--description, --create/--private, and a network-free --dry-run.
  • repo — repo create and repo delete (deletion requires --yes).
  • tag — tag create, tag list, and tag delete (deletion requires --yes).

Write operations require a token with write access, resolved from --token, $HF_TOKEN, or the huggingface-cli login token file. Flags must precede the positional arguments.

hftools upload --message "add weights" owner/model ./local_dir
hftools repo create --private owner/model
hftools tag create --message "release" owner/model v1.0

Zero external dependencies; static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.

hftools v0.10.0

Choose a tag to compare

@ziozzang ziozzang released this 16 Jul 13:29

Absorbs the read-side features of the official huggingface-cli.

  • Spaces are now a first-class repository type: pass --type space to the inspection commands, or download one with hftools space owner/name.
  • search — query the Hub for models, datasets, or spaces (--author, --filter, --limit, --sort).
  • refs — list a repository's branches and tags.
  • whoami — show the identity your token authenticates as.
  • cache-scan — summarize disk usage of a Hugging Face cache.
  • Token interop — when --token/$HF_TOKEN are unset, hftools reads the huggingface_hub token file ($HF_TOKEN_PATH, $HF_HOME/token, or ~/.cache/huggingface/token), so a token from huggingface-cli login is picked up automatically.

All new remote commands support --json.

Static builds for macOS, Windows, and Linux on ARM64 and x86-64. Verify with SHA256SUMS.

Created by Jioh L. Jung — https://github.com/ziozzang/hftools

hftools v0.9.2

Choose a tag to compare

@ziozzang ziozzang released this 16 Jul 13:17

Refines the self-update experience.

  • Background version check — the update-available lookup now runs in a background goroutine and the foreground never waits on it. Offline/air-gapped machines are no longer slowed down: the check times out and soft-fails silently. The one-line notice is printed from a cached result.
  • Release notes on upgrade — hftools update prints the new version's release notes after replacing the binary.
  • hftools doctor now reports update status (up to date / update available / could not reach GitHub), so an air-gapped "could not check" surfaces in diagnostics rather than as per-command noise.

HFTOOLS_NO_UPDATE_CHECK=1 disables the check entirely.

Static builds for macOS, Windows, and Linux on ARM64 and x86-64. Verify with SHA256SUMS.

Created by Jioh L. Jung — https://github.com/ziozzang/hftools

hftools v0.9.1

Choose a tag to compare

@ziozzang ziozzang released this 16 Jul 13:04

New: update-available notice

After a command, hftools prints a single line when a newer release exists:

hftools 0.9.1 is available (you have 0.9.0). Run 'hftools update' to upgrade.

It is intentionally quiet:

  • Checks at most once a day (result cached under the user cache dir), so no per-command network cost.
  • Only shown when stderr is a terminal — scripts and piped/--json output are never disturbed.
  • Never blocks (3s timeout) or fails the command, and works fine offline.
  • Never installs anything; upgrading stays the explicit hftools update.
  • Disable entirely with HFTOOLS_NO_UPDATE_CHECK=1.

Static builds for macOS, Windows, and Linux on ARM64 and x86-64. Verify with SHA256SUMS.

Created by Jioh L. Jung — https://github.com/ziozzang/hftools