Repository navigation
Releases: ziozzang/hftools
Release list
hftools v0.15.1
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-identityonverify,verify-batch, andverify-sigrejects such records outright (exit 1) instead of relying on the reader.require_signed_identity: truein~/.hftools/config.yamlenforces 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-identityCross-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
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
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
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--scanruns the pickle/torch unsafe-import scan on each repository; a critical finding fails that repository.--verify-sigverifies 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
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_signis the persistent switch:hftools key init --auto-signturns it on (creating the identity on first use).--sign/--sign=falseoverrides the config default per run, ondownload/dataset/space/batchandverify/verify-batch.- verify signs only on a clean pass;
watchsigns 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 runRecipients 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
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.
~/.hftoolshome store (override with$HFTOOLS_HOME): an ed25519 private key (signing.key, mode 0600), its public key (signing.pub), and aconfig.yamlholding the signer label and atrusted_keysregistry. Still zero external dependencies —config.yamluses a small built-in YAML reader.signwith no--keyuses the home identity, creating it (key +config.yaml) on first run, and defaults the signer label from config.verify-sigauto-recognizes a signer whose key you have trusted (reportstrusted key: NAME);--pubkeynow also accepts a trusted name. It always prints the key's SHA-256 fingerprint, and when the key is unpinned/untrusted it suggests thekey trustcommand.- New
keycommand: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 keyHashing 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
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 createandrepo delete(deletion requires--yes). - tag —
tag create,tag list, andtag 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.0Zero external dependencies; static binaries for macOS, Windows, and Linux on ARM64 and x86-64. Verify a download against SHA256SUMS.
hftools v0.10.0
Absorbs the read-side features of the official huggingface-cli.
- Spaces are now a first-class repository type: pass
--type spaceto the inspection commands, or download one withhftools 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_TOKENare unset, hftools reads thehuggingface_hubtoken file ($HF_TOKEN_PATH,$HF_HOME/token, or~/.cache/huggingface/token), so a token fromhuggingface-cli loginis 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
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 updateprints the new version's release notes after replacing the binary. hftools doctornow 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
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/
--jsonoutput 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