← All posts
Blog

No-Hash Zone: stop your AI agent from fingerprinting your private files

Shout-out: Claude Code hooks ↗

I let AI coding agents do a lot of the chores on my machines: moving files around, cleaning up folders, writing the little scripts nobody wants to write. They're good at it. But they all share one reflex I don't want anywhere near private files: when you ask them to check something, they hash it.

"Copy these clips to the backup drive and make sure nothing got corrupted" turns into sha256sum on both sides. "Find the duplicates" turns into fdupes. "Keep these in sync" turns into rsync. A quick indexing script grows a hashlib cache key. For source code that's exactly what you want. For private media it isn't, so I built a fence around it and open-sourced it: No-Hash Zone.

Why a hash counts as a leak

A hash feels harmless. It's a short string of hex, you can't turn it back into the file, so who cares? Here's who:

If you work with unreleased footage, client shoots, interviews, legal or medical scans, or anything under an NDA, that's a problem you never signed up for.

What No-Hash Zone is

Two layers for Claude Code, and each one covers the other's blind spot:

The policy handles judgement: the tool nobody thought to list, the subagent it might hand the job to. The guard handles the moment a rule gets lost three hours into a long session.

How the guard decides

Claude Code hands the pending command to the hook as JSON. The hook lower-cases it, turns backslashes into forward slashes, and asks two questions: does this command mention a protected location, or run from inside one? And does it use something that derives a value from file contents? Two yeses and it answers with a deny:

Claude wants to run:  rsync -a /Volumes/Private/shoot-0412/ /Volumes/Backup/shoot-0412/

The guard answers:    deny
                      "No-hash zone: this command would hash, checksum or fingerprint
                      files in a protected location (rsync and content-based dedup
                      included). Work from metadata instead (names, sizes, dates),
                      or ask the owner."

Claude Code doesn't run the command, and the agent reads the reason and changes course. Each protected location is matched in every spelling a shell might use: either slash direction, any letter case, ~ and $HOME, the Git Bash and WSL forms of a Windows drive, and smb:// for a network share. It also fails closed: if the guard can't read its input or its config, or can't start at all, the command doesn't run.

It knows the obvious tools (md5, the sha*sum family, Get-FileHash, certutil -hashfile, hashlib, crypto.createHash), the duplicate finders, and the sync and backup tools that checksum or chunk content (rsync, rclone, restic, borg, git add). It also knows the ones media people actually trip over: ffmpeg's md5 and framemd5 outputs, ImageMagick's %# image signature, ExifTool's image-data hash and the perceptual-hash libraries.

What changes day to day

Not much, and that's the point. The agent still copies, moves, lists, renames and organizes everything. It just checks a copy by names, counts and sizes, flags likely duplicates by name and size, and builds its indexes from metadata. When a job genuinely needs a content comparison, it stops and asks instead of doing it quietly. Hashing a download in ~/Downloads still works fine; only the places you list are fenced off.

Install

You need Claude Code and Node.js 18 or newer. Clone it and tell it what to protect:

git clone https://github.com/AcidAlchamy/no-hash-zone.git
cd no-hash-zone
node install.mjs --path "/Volumes/Private" --path "$HOME/Clients"

On Windows it's the same with Windows paths: --path "D:\Private" --path "\\nas\clients". The installer copies the guard, writes your list, adds one entry to settings.json and puts the policy at the top of your CLAUDE.md, backing both files up first. --dry-run shows what it would do, --uninstall takes it back out. Then start a new session.

Honest limits

It's a seatbelt, not a vault. For hard isolation, use the operating system: file permissions, a separate account, an encrypted volume that stays locked.

Get it

No-Hash Zone is free and open source under Apache-2.0: github.com/AcidAlchamy/no-hash-zone. It's about 150 lines of dependency-free JavaScript plus a policy you can read in five minutes, and its 39-case test suite passes on macOS, Linux and Windows. If your agent works anywhere near files that aren't yours to fingerprint, put a fence around them.