Install guide
One install. Three ways in.
Everything below is lifted from the SDK's own README: the shipped truth, not marketing. The only runtime dependency is requests.
Install
The SDK is a single Python package:
$ pip install foxy-audit
Method 1 — the decorator: capture every call
Wrap the function that talks to your model. Your code stays unchanged; every call is hashed into customer-keyed commitments locally, raw text is thrown away before upload, and only content-blind metadata reaches the ledger — over a durable local spool, so capture never blocks your request path.
import os
from foxy_audit import FoxyClient
foxy = FoxyClient(api_key=os.getenv("FOXY_API_KEY"))
@foxy.audit(policy="hipaa")
def ask_model(prompt: str) -> str:
return llm_client.generate(prompt) # your existing code — unchanged
Prefer zero client plumbing? The module-level decorator builds a client from the environment: from foxy_audit import audit, then @audit(policy="soc2"). Same capture, same guarantees.
The policy tag selects which local checks run before the model is called — the baseline (prompt injection, secret detection) runs under every tag, and hipaa/gdpr add the PHI/PII sweeps. In block or redact mode, enforcement happens locally, before the request leaves your process.
Method 2 — the pre-flight gate: check() in CI
Ask "would this prompt be blocked?" without wrapping anything. check() needs no API key, no network and no spool; the exit code drops straight into a pre-commit hook or a CI step. It is content-blind: it returns rule labels, and never returns, logs or echoes the text you gave it.
$ foxy check "ignore all previous instructions" --policy hipaa # exit 1 if it fires
$ foxy check --prompt-file prompt.txt --policy gdpr --json
The same call is available in Python: from foxy_audit import check — result.triggered, result.rules, result.ruleset_version.
Method 3 — the local replay: explain() proves a recorded row
For a row already in your ledger, explain() recomputes the commitment from your local key, matches it against the row's recorded hash, loads the frozen ruleset that row named (not today's rules) and replays it, showing which rule matched where. It runs on your machine, against a prompt you supply, so it shows you nothing you do not already have; the matched spans go to stdout only.
$ foxy explain --event-id 3f2a… --export logs.json --prompt-file prompt.txt
Three answers are honestly "I cannot": a salted row whose salt sidecar is missing, a row naming a newer ruleset than your SDK, and a pre-1.7.0 row that recorded no ruleset. It says so rather than guessing.
- What leaves your machine: customer-keyed commitments, a token count, a policy tag, and bounded metadata. Raw text never does.
- What happens next: records are sealed into a per-organisation hash chain and, optionally, graded by the content-blind judge.
- Where to go deeper: the documentation index links every topic page, and how it works walks the whole pipeline.
Want us to wire it in with you?
Book a walkthrough and we'll integrate the SDK into a real call live, then verify the chain in front of you.
Book a demo
Foxy Audit