Handcuff is a security-first observability tool for AI agents, featuring tamper-evident OS-level recording, prompt-injection circuit breakers, and Docker sandboxing.
Project description
Handcuff — an antivirus for AI agents
Handcuff is a security-first observability and enforcement tool for AI agents. It records what an agent does at the OS level in a tamper-evident, hash-chained log — and it can stop malicious content before an agent ever sees it, through a detonate-and-verdict sandbox and, on Windows, a signed kernel driver that blocks file opens and process launches in Ring-0.
Full architecture diagrams, TUI screenshots, and the complete guide live on the Handcuff GitHub repository — this page covers install and the essentials.
Key features
- Tamper-evident recording — every event is SHA-256 hash-chained and the session head is Ed25519-signed.
handcuff verifyre-validates the chain from the live database or an exported report. - Sandbox analysis before admission —
SandboxAnalyzergives every intercepted download (and MCP tool payload) an approve/reject verdict before the agent receives it: static risk-indicator analysis always, plus detonation in a hardened, network-less Docker container when available. Falls back to static-only with no Docker installed — nothing breaks. - Kernel-level enforcement (Windows, optional) — a signed minifilter driver denies file opens and process launches for anything flagged, even for a process that never calls into Handcuff. Content-hash matching catches a copy/rename of previously-flagged bytes. The deny-list persists and re-applies itself across reboots.
- MCP proxy firewall —
handcuff mcpinterceptstools/callrequests, scans them with a regex injection detector plus an optional local LLM judge (Ollama, 100% local), and returns a proper JSON-RPC error for a blocked call instead of forwarding it. - Prompt-injection circuit breaker —
handcuff.gateway.Gatewayimplements taint-tracking: once untrusted content is read, further network egress and out-of-workspace reads are denied for a window, cutting Simon Willison's "lethal trifecta" before it completes. - Live dashboard —
handcuff tuishows the event stream, risk score, alerts, and a kernel-enforcement panel in real time. - Local-only — nothing leaves your machine except an optional, content-light webhook you configure yourself.
Install
Requires Python 3.10+.
pip install handcuff
Optional extras, install only what you need:
pip install "handcuff[proxy]" # mitmproxy, for the download-interception proxy
pip install "handcuff[sandbox]" # docker SDK, for dynamic sandbox detonation
pip install "handcuff[mcp]" # mcp package
pip install "handcuff[langchain]" # langchain-core, for the HandcuffHandler callback
Quickstart
handcuff init
Environment readiness:
[ ok ] Config file: ~/.config/handcuff/config.yaml
[ -- ] mitmproxy (download proxy): mitmdump not found
[ -- ] Docker (dynamic sandbox): not available
[ -- ] Ollama (LLM judge): not reachable
[ -- ] Kernel driver (Ring-0 enforcement): not loaded
Each unchecked item is optional - the tool works with whatever is available.
handcuff watch -- python my_agent.py
session 01KXG26CAXY0XB65RMG05EGHFD closed
handcuff verify 01KXG26CAXY0XB65RMG05EGHFD
chain: OK
signature: OK
Check a file before you trust it, no Docker required:
handcuff sandbox analyze ./suspicious_script.sh
REJECTED - high-risk static indicators
method: static-fallback
indicators: disk_wipe
The CLI, at a glance
handcuff watch -- <command> # record OS-level activity for <command>
handcuff mcp -- <command> # MCP stdio proxy with tool-call scanning
handcuff proxy # download interception proxy
handcuff sandbox analyze <file> # detonate/analyze verdict for a file
handcuff kernel status # kernel driver load state + quarantine count
handcuff kernel quarantine <path> # deny file opens for <path>
handcuff kernel watch <dir> # background auto-quarantine
handcuff tui # live dashboard
handcuff verify <session_id> # re-validate hash chain + signature
handcuff doctor # full environment diagnostics
Every command supports --help.
Python integration
from handcuff.integrations.langchain import HandcuffHandler
handler = HandcuffHandler()
result = my_agent.invoke(
{"input": "Do some research"},
config={"callbacks": [handler]},
)
handler.close()
from handcuff.sandbox.manager import DockerSandbox
# Hardened defaults: no network, read-only root fs, capability drop,
# memory/pids/CPU ceilings.
with DockerSandbox(allow_network=True) as sandbox:
sandbox.execute("curl -sO https://example.com/untrusted_data.csv")
# Runs the injection scanner + a native-executable check before the
# file ever reaches the host; raises QuarantineViolation and discards
# it on a match instead.
sandbox.copy_quarantined(
container_path="/sandbox/untrusted_data.csv",
host_path="./host_workspace/clean_data.csv",
)
Honest scope
- The regex/heuristic injection scanner is a tripwire against known patterns, not a semantic guarantee.
- The Gateway and MCP proxy only secure agents whose tool-calling layer routes through them — an agent with raw shell access bypasses both. The kernel driver is the only layer that doesn't depend on agent cooperation, and it requires Windows plus a one-time signed build; nothing else in Handcuff requires it.
- Dynamic sandbox execution runs scripts, not opaque binaries, and container isolation is a strong mitigation, not a zero-risk guarantee.
Full documentation
Architecture diagrams, the complete CLI/config reference, the kernel driver build/sign workflow, and contributing guidelines: github.com/Mister2005/Handcuff.
Handcuff currently prioritizes the Windows ecosystem (psutil, watchdog, Windows ACL/Firewall, the kernel driver). macOS and Linux are partially supported by the underlying capture abstractions, but enforcement (ACL/firewall/kernel) is Windows-only today.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file handcuff-1.16.1.tar.gz.
File metadata
- Download URL: handcuff-1.16.1.tar.gz
- Upload date:
- Size: 533.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89c184fc5a71bb943d26a5e7d9193cc90b82e495cd7d86c98749aa39a2d23d1a
|
|
| MD5 |
ba19507f0b83699511a76b0ac9690e6e
|
|
| BLAKE2b-256 |
511f109a54c14f96dddb219af46f92f4b095e287e571cf5684d913bbca7c5875
|
File details
Details for the file handcuff-1.16.1-py3-none-any.whl.
File metadata
- Download URL: handcuff-1.16.1-py3-none-any.whl
- Upload date:
- Size: 153.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32b3d5902ece536532bbfeacb6a7317cb1ddd664e56dadb2eaf7fd33791db549
|
|
| MD5 |
03bedbd8c885fc1f492be7c007732ca2
|
|
| BLAKE2b-256 |
8128145747af13b0348981f1c3e00e21313e476d17ed7cad9d0e0edeb44d71d8
|