Crawdad is built to protect AI agents in adversarial environments. This page describes how we protect you and your data.
Crawdad is a local security tool for teams deploying autonomous AI agents. The sidecar runs entirely on your machine. Metadata-only telemetry (event counts, categories, verdicts) egresses by default, raw content (prompts, responses, action parameters, PII) never does. This is enforced by a sanitization chokepoint in the architecture, not policy. Telemetry depth is customer-governed and off by default; enabling content-carrying (full) telemetry requires explicit authorization and is recorded in the audit chain. The one opt-in exception is the L7 cloud LLM Judge (off by default, gated behind an explicit warning), which sends content to a third-party model if you enable a cloud backend. The system is implemented in Rust for memory safety; 3,737 automated tests across 26 crates (mechanically counted 2026-08-22; run grep -rhoE '#\[(tokio::)?test\]' --include='*.rs' crawdad-* to reproduce).
Five architectural invariants are property-tested over 1,000,000 iterations on every release by the crawdad-zk-verify crate. A standalone getcrawdad/zk-verify MIT reproducer is on the roadmap so any operator can confirm the invariants against a running sidecar independently.
Crawdad's detection claims are reproducible. The AndrewSispoidis/contemporary-agent-attacks repository contains 497 attacks across 22 categories, 1,172 benign samples across 4 sources, and a tool-agnostic benchmark runner, licensed CC-BY 4.0 so any operator, researcher, or competing vendor can run it against any classifier.
Current Crawdad result on the public corpus (full detection engine, ML on every input; last full re-verify 2026-08-02): 496/497 = 99.80% detection, 0.09% false-positive rate (1/1,172), F1 99.80%. The visible set is 395/395 (100%); the single miss is a bare social-engineering pretext opener in the 102-sample holdout. The one false positive is a StackOverflow question about Go method receivers (with GitHub source links), flagged by the pattern layers, not ML. Without the ML layer the pattern-only floor is 37.8%, ML is a booster, not a gate.
Detection is not the same as blocking. The 99.80% figure is a detection-engine measurement, not a “protection rate.” The ML classifier runs on every input (no prefilter gates inference); what varies is blocking. The credential and data-exfiltration floors always block inline. For every other detection, the arbiter promotes a single high-confidence hit (ML or dynamic signature, confidence at or above 0.70) to an inline block, which puts proxy-path blocking at 99.80% on this corpus at an unchanged 0.09% false-positive rate and microseconds of added arbiter cost, measured in-process on the same benchmark. Detection and blocking are reported separately because they are separate mechanisms; here they coincide because the arbiter is built to make them coincide. No external party has independently re-run the corpus against a running sidecar yet.
Reproduce it:
git clone https://github.com/AndrewSispoidis/contemporary-agent-attacks
cd contemporary-agent-attacks
python3 benchmark/run.py --adapter adapters.crawdad --tool crawdad-v1.7.1
The benchmark runner accepts adapters for any tool exposing an HTTP scan endpoint, see CONTRIBUTING.md for submission guidelines.
Every agent that talks to Crawdad runs at one of four trust levels: Autonomous (full L1–L6 detection, L7 skipped, no restrictions), Monitored (full L1–L7, default for new agents), Restricted (full pipeline + active per-tool-call restrictions), Quarantined (all requests return HTTP 403 before detection runs).
Scope of v1.0. What ships: per-agent attribution, the four levels, automatic escalation with the rules above, auto-recovery, default restrictions on entry to Restricted, audited transitions. What's roadmap: fleet-wide policy hierarchy, cross-device trust sync, industry policy templates.
Governance plane. At the agent↔tool boundary, Crawdad enforces autonomy ceilings (read-only through privileged), security zones, blanket per-tool rules, and a cumulative session-risk budget, composed most-restrictive-wins and authored in a policy file. Each primitive is proven by an over-the-wire block test against the real proxy.
Contextual Agency Governance. An opt-in charter governs an agent by purpose: an operator-declared allowlist over the tools, data, and effects its job needs, held outside the agent's control and enforced on the observed action, so a deceptive stated intent buys nothing and an out-of-charter action is blocked at the wire with the axis named. A trajectory layer watches the shape of the whole session for staged compromise (enumerate, read progressively more sensitive in-scope data, then send) that no single-action check would catch, with deterministic sensitivity-anchored signals plus an on-device reasoner gated onto only the ambiguous cases; a completed staging chain is held for review when no local model is reachable, never silently allowed. Ordinary multi-step work is measured at zero false positives, and it does not claim to catch every composed harm. Every charter and trajectory decision is recorded to the tamper-evident audit chain, metadata only, and surfaced on the local dashboard (live feed, per-session risk, a review queue with a real engine effect, and charter authoring that governs at the wire) and rolled up per client and across clients in the Fleet Console.
Crawdad ships a remote control plane that lets operators monitor agents and change trust levels from a paired phone. The plane is built so the on-device guarantee still holds, the relay sees only encrypted blobs and opaque device IDs, and a layered set of controls bounds what a paired device (or a compromised one) can do.
pairing_db SQLite file (WAL, synchronous=NORMAL) separate from the audit and metering databases, so recovery or rotation of one domain does not touch the others.Read, Bash, WebSearch). If your agents use custom-named tools that could reveal the nature of your work, enable "Anonymize tool names" in Settings to replace them with generic categories (file_read, file_write, shell, web, api_call, other) before they leave your machine. The local audit trail and dashboard always show the real names, the mapping only applies to the encrypted snapshot pushed to paired devices. Startup default is off; flip at runtime via Settings (desktop or mobile) or set CRAWDAD_ANONYMIZE_TOOLS=1 to enable at boot.NIST 800-53 alignment. Relevant controls: AC-2 (account management, paired device lifecycle), AC-3 (access enforcement, signature + scope checks), AC-7 (unsuccessful logon attempts, rate limits), AU-2/AU-3 (auditable events, every accepted command audited), IA-2 (identification & authentication, Ed25519 per-device), SC-8 (transmission confidentiality, AES-256-GCM relay), SC-13 (cryptographic protection, Ed25519 + AES-GCM), SI-4 (system monitoring, local kill switch + audit trail).
Mode-changing endpoints (/api/v1/mode and /api/v1/mode/unpause) are mounted only on the management API and are not reachable from the proxy data path. A prompt-injection payload that arrives through traffic on the provider proxy ports cannot trigger a mode change or pause. Mode changes from a paired mobile device are signed and audited. Pause does not unquarantine quarantined agents, quarantine state is independent of mode. Allow-Always rules continue to apply at every mode.
Forensic logging continues at every mode. When a detection would have blocked but is suppressed by Reduced or Paused mode, an audit_events row is recorded with action_taken="suppressed_by_mode" and a detail JSON containing the layer, category, protection_mode at time of event, and agent identity. The spec promise, "audit log gets fuller, never thinner, when protection is reduced", holds.
~/Library/Application Support/crawdad/ on macOS, ~/.local/share/crawdad/ on Linux, %APPDATA%\crawdad\ on Windows). The directory is created with owner-only permissions (0700) and the sidecar refuses to start on a group- or world-accessible path. Crawdad does not transmit content to any external server.entry_hash = SHA-256(prev_hash ‖ table ‖ row ‖ content_hash ‖ time). Any modification to a past entry invalidates all subsequent hashes.crawdad verify-chain or the standalone source-available crawdad-verify (no network, no service, no secrets from the machine). Tamper-evidence holds against an attacker with database write access; to raise the bar past a root/same-user attacker who could re-sign a rewritten chain, the chain head can be anchored to an external witness (opt-in), and crawdad-verify --anchor cross-checks the live database against that off-machine record, catching a re-signed rewrite that internal verification alone would pass.If you discover a security vulnerability in Crawdad, please report it through the contact form at getcrawdad.dev. We commit to a 24-hour initial response and will work with you to understand and resolve the issue before any public disclosure. We do not pursue legal action against good-faith security researchers.
For security questions, vulnerability reports, or compliance inquiries: