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.
Metadata
Release files for handcuff 1.16.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| handcuff-1.16.3.tar.gz | 533.9 kB | Without provenance | Details for handcuff-1.16.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| handcuff-1.16.3-py3-none-any.whl | Python 3 | none | any | Details for handcuff-1.16.3-py3-none-any.whl |
Total release size: 687.5 kB
Release files / handcuff-1.16.3.tar.gz
| Download URL | handcuff-1.16.3.tar.gz |
|---|---|
| Size | 533.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7589ff7718ed4ffba768574c0ab2be2743c21a6dbaf8e81cd3cd20abdcd5311f
|
|
BLAKE2b-256 checksum How to use checksums |
a6df0387906f1ca9540acdab854cfc7f0417f664fb155eb103db34473925743b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.11
|
Release files / handcuff-1.16.3-py3-none-any.whl
| Download URL | handcuff-1.16.3-py3-none-any.whl |
|---|---|
| Size | 153.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
21823b31ad68b1ffce76d0adc46c619ee5c8d4b9f77d5b4e34208d8bd6dc7c0e
|
|
BLAKE2b-256 checksum How to use checksums |
9e6ab97e13e77f463b8fd079b368f7cc63475bc5840f402757d88dd31297d7e3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.11
|
Security for handcuff 1.16.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.