Detect, analyze, and report AI execution artifacts on a host machine.
vettd is a Rust CLI tool that scans your system for AI-related configuration files — things like .cursorrules, MCP server configs, prompt files, and container definitions — analyzes them for risk, and produces structured reports.
If Vettd helps your team, you can support ongoing open source development with a donation via Stripe:
vettd is local-first. It walks your filesystem, identifies AI execution artifacts, scores them for risk, and writes results locally. Network activity only happens when you explicitly opt into submission-related flows or vettd update. vettd auth only saves local configuration.
If you want a hosted review, policy, and governance surface, vettd can submit to compatible ingest APIs. You can configure an endpoint during setup or pass one directly at submission time.
| Requirement | Detail |
|---|---|
| OS | macOS (ARM64, x86_64), Linux (ARM64, x86_64), Windows (x86_64) |
| Runtime | None — official releases are single binaries with no sidecar service |
| Build | Rust 1.85.1+ (pinned via rust-toolchain.toml) |
| Network | Optional — only needed for submission-related flows and self-update |
| Disk | ~15-25 MB for the binary depending on platform; reports are only written when requested |
brew tap AgenticHighway/tap
brew install vettd
vettd scan quickHomebrew is the smoothest install path on macOS while direct-download artifacts are not yet signed and notarized.
Download the latest binary for your platform from GitHub Releases.
# macOS (Apple Silicon)
tar xzf vettd-darwin-arm64.tar.gz
./vettd scan quick
# Linux (x86_64)
tar xzf vettd-linux-amd64.tar.gz
./vettd scan quickEach GitHub Release includes checksums.txt (SHA-256 hashes for all
release assets) and checksums.txt.sig (a KMS ECDSA signature over
checksums.txt, using the same key that vettd update trusts).
# Download the binary and checksums for your platform, then:
# Linux — verify SHA-256
sha256sum --check --ignore-missing checksums.txt
# macOS — verify SHA-256
shasum -a 256 --check --ignore-missing checksums.txtFor the full signature-verification procedure (including how to verify
checksums.txt.sig with the embedded public key), see
docs/release-verification.md.
git clone https://github.com/AgenticHighway/vettd-cli.git
cd vettd
cargo build --release
./target/release/vettd scan quickvettd # Interactive wizard — walks you through options
vettd scan quick # Tier 1 scan of critical AI config areas (~/.cursor, VS Code, Claude, etc.)
vettd scan default # Default tiered scan of critical roots + bounded user-space/project roots
vettd scan full # Deep system-wide scan (slow, thorough)
vettd scan file <path> # Scan a single file
vettd scan folder <path> # Scan a directory
vettd scan repo <path> # Deep-scan a git repository
vettd auth # Prompt securely for an API key and save it
vettd auth --key <key> # Save API credentials directly (useful for automation)
vettd auth status # Show auth/identity status
vettd contract status # Show local vs. server contract status
vettd directory <cmd> # Browse the public directory: search|list|random|view|findings|compare
vettd update # Check for and install updates
vettd rules list # List installed custom detection rules
vettd rules add <file> # Install a TOML rule file
vettd rules remove <name> # Remove an installed rule by name
vettd rules validate <f> # Validate a rule file without installingvettd now treats scan modes as scan-surface tiers instead of simple breadth presets:
quick: Tier 1 only — critical OS-aware agent surfaces such as VS Code, Cursor, Claude, Continue, Aider, and similar local tool config rootsscan: Tier 1 plus bounded user-space/project roots such asDesktop,Documents,Downloads, and common repo folders likeCode,Projects,Workspace,src, andGitHubfolder: explicit target directory plus bounded local adjacencyrepo: explicit target repository plus deeper local adjacencyfull: explicit forensic sweep from filesystem root
Current critical roots are OS-aware:
- macOS:
~/Library/Application Support/Code/User,~/Library/Application Support/Code - Insiders/User,~/Library/Application Support/Cursor/User, plus~/.claude,~/.cursor,~/.aider,~/.continue,~/.ollama, and editor config roots when present - Linux:
~/.config/Code/User,~/.config/Code - Insiders/User,~/.config/Cursor/User, plus~/.claude,~/.cursor,~/.aider,~/.continue, and~/.ollama - Windows:
%APPDATA%\\Code\\User,%APPDATA%\\Code - Insiders\\User,%APPDATA%\\Cursor\\User, plus%USERPROFILE%\\.claude,%USERPROFILE%\\.cursor,%USERPROFILE%\\.aider,%USERPROFILE%\\.continue, and%USERPROFILE%\\.ollama
vettd scan quick # Overview with risk bars (default)
vettd scan quick --full # Detailed per-artifact breakdown
vettd scan quick --summary # Compact statistics only
vettd scan quick --json # JSON report to stdout
vettd scan quick --out # JSON report to ./vettd-report.json
vettd scan quick --out r.json # JSON report to a custom path
vettd scan quick --contract # Scanner data contract JSON to stdout
vettd scan quick --contract --out r.json # Contract JSON to file
vettd scan quick --contract --submit --api-key <key> # Contract to file + submit--json, --out, and --contract all emit the scanner data contract
shape used for compatible ingest APIs and local automation.
The table below is representative, not exhaustive. vettd combines built-in detectors, packaged TOML rules, and optional custom rules, so additional file names and patterns may be detected beyond these common examples. For deeper detector details, see docs/detectors.md.
| Detector | Files | What it looks for |
|---|---|---|
| Cursor / editor rules | .cursorrules, agents.md, AGENTS.md |
AI instruction files with capability keywords (TOML rule) |
| Prompt configs | *.prompt.md, *.instructions.md, copilot-instructions.md |
Prompt configuration for GitHub Copilot and similar (TOML rule) |
| MCP configs | mcp.json, claude_desktop_config.json |
Model Context Protocol server declarations |
| Container configs | Dockerfile, compose.yaml, docker-compose.yml |
Docker image definitions and service orchestration with direct AI evidence or nearby agent artifacts |
| Browser footprints | Chrome, Edge, Brave, Arc profiles | Extension directory presence only (no content reads) |
| Custom rules | Any .toml in ~/.vettd/rules/ |
Declarative rules you define |
Every artifact gets a risk score from 0–100:
| Score | Severity | Color | Meaning |
|---|---|---|---|
| 90+ | CRITICAL | Magenta | Credential exposure or extreme risk |
| 70-89 | HIGH | Red | Dangerous capability combinations |
| 40-69 | MEDIUM | Yellow | Notable capabilities worth reviewing |
| 10-39 | LOW | Cyan | Minor signals, likely benign |
| 0-9 | INFO | Dim | Informational only |
Scores are based on: artifact type, detected capability keywords (shell, network, filesystem, etc.), dangerous keywords (exfiltrate, steal, bypass, etc.), and whether capabilities are explicitly declared.
By default, vettd shows the full local report.
If you want to locally limit terminal console findings to the top three
visible artifacts, create ~/.vettd/.vettd.toml (per-user location):
[access]
mode = "lite"
# search_beta_testing = true # opt into --language, --agent-compatibility,
# # and --rankings filters (POST request shape)Beta search filters:
search_beta_testing = truein the config enables the--language,--agent-compatibility, and--rankingssearch filters and switches the directory request to POST with a JSON body. TheSEARCH_BETA_TESTINGenvironment variable (set to1ortrue) takes precedence over this config entry and can enable the same behavior without touching the config file.
When the file is absent, vettd keeps full output enabled.
Where the config lives:
~/.vettd/.vettd.toml(per-user only). A.vettd.tomlin a scanned project directory is never consulted — a scanned repo must never be able to self-gate its own findings.Display-only gate:
--out,--contract,--submit,--json, and--stdoutalways carry the full un-truncated findings regardless of access tier. The lite limit applies to the terminal console only.
vettd supports hosted submission flows through compatible ingest APIs. You can configure an endpoint during setup or pass one directly for self-hosting, testing, or interoperability.
With an API key configured:
# Prompt securely for credentials
vettd auth
# Or set credentials directly for automation
vettd auth --key your-api-key
# Submit scan results (uses saved endpoint)
vettd scan repo . --submit --api-key your-key
# Submit to a custom public endpoint — requires --allow-public-endpoint
vettd scan repo . --submit https://example.com/api/scans/ingest \
--allow-public-endpoint --api-key your-key
# Save a custom public endpoint for future use — also requires the flag
vettd auth --key your-api-key \
--endpoint https://example.com/api/scans/ingest \
--allow-public-endpointEach submission payload contains:
- Scan root paths — the filesystem paths where the scan ran (e.g.
/Users/you) - Machine hostname — the host's reported hostname
- AI artifact metadata — file paths, content hashes, capability signals, and risk scores for detected artifacts
- MCP server config metadata — server commands, tool names, and env-var names (values are never transmitted)
- Host security context — macOS firewall state on macOS; empty on other platforms
- Scanner metadata — version, OS, and architecture
No file contents, secret values, or credential material are transmitted.
In interactive flows (vettd scan quick / vettd scan repo / etc. from a terminal), vettd displays this summary and asks for confirmation before sending.
In automation flows (--submit --api-key …), the submission proceeds without a prompt. Review the data categories above before embedding vettd in CI/CD pipelines.
By default, vettd blocks submission to public (non-localhost, non-private-network) endpoints at the flag level. This prevents accidental data exfiltration in scripts that omit an explicit endpoint. Pass --allow-public-endpoint when you intentionally want to submit to or save a public endpoint.
Local endpoints (localhost, 127.0.0.1, ::1, RFC-1918 addresses) are always allowed without the flag.
- Scans stay local unless you explicitly opt into connected commands
- Compatible submission endpoints are supported, whether configured ahead of time or passed on the command line
- Contract sync only runs during explicit submission flows, when the target endpoint exposes a compatible contract API
- Retry logic handles transient failures (429, 502, 503, 504)
- On Unix-like systems, saved API keys are written to
~/.config/vettd/config.jsonand vettd explicitly tightens directory/file permissions to0700/0600 - On Windows, saved API keys are written under the current user's config directory, typically
%APPDATA%\\vettd\\config.json, and currently rely on the default per-user profile ACLs rather than explicit ACL hardening by vettd
vettd update # Check for and install updates
vettd update --check # Check only, don't install
vettd update --force # Force update even if currentvettd update explicitly checks for the latest release, verifies the signed
manifest, checks the matching artifact SHA-256, and replaces the local binary.
Official release binaries verify a detached AWS KMS-backed ECDSA signature on the update manifest before trusting artifact URLs or hashes.
Source builds remain fully functional, but vettd update will fail explicitly
unless the binary was built with PROOV_UPDATE_PUBLIC_KEY_DER_B64 set at
compile time.
Every interactive prompt has a flag (or subcommand) equivalent, so vettd can
run unattended in CI, scripts, and agents. When stdin is not a TTY the prompts
are never shown: each command below either takes its explicit input or exits
non-zero with guidance, rather than blocking on input.
| Interactive prompt | Non-interactive equivalent |
|---|---|
Scan type picker (vettd scan with no subcommand) |
vettd scan quick (or full, default, folder <path>, file <path>) |
| Save / submit menu after a local scan | --out <path> to write a report; vettd scan submit <report> to submit |
| "Report path" prompt | --out <path> |
API key prompt (vettd auth) |
vettd auth --key <key> |
Update confirmation (vettd update) |
vettd update --force |
Without a TTY and without the equivalent flag, vettd scan, vettd auth, and
vettd update exit non-zero with a message naming the flag to use.
- Path-first scanning — content is only read from specific allowlisted file types
- Bounded walking — max depth of 5 for shallow scans; full scan enumerates the entire filesystem with no caps
- Scoped exclusions —
.git/,node_modules/,.venv/,target/and similar are excluded from default, workdir, and filesystem scans (full scan has no exclusions) - Secret detection without storage — token patterns trigger a signal tag, but values are never stored or transmitted
- Browser presence only — extension directories are noted, but no extension content or preferences are read
- Declarative rules — custom rules are TOML config files; they use the same content-read allowlist as built-in detectors
vettd/
├── crates/
│ └── vettd/ # CLI binary (scanning, detection, submission)
│ └── src/
│ ├── detectors/ # Built-in artifact detectors
│ └── contract/ # Scanner data contract builders
├── rules/ # Built-in TOML detection rules (compiled into binary)
├── examples/
│ └── rules/ # Example custom detection rules (.toml)
├── scripts/
│ ├── test-scanner.sh # Automated test suite
│ └── test-submit.sh # Manual submission test
├── docs/
│ ├── architecture.md # System design and data flow
│ ├── user-flows.md # Public CLI journeys and UX paths
│ ├── detectors.md # How detection works
│ ├── output-spec.md # Plain-English spec for contract outputs
│ └── custom-rules.md # Writing custom detection rules
├── .github/
│ ├── workflows/
│ │ ├── ci.yml # PR checks: fmt, clippy, test, audit
│ │ └── release.yml # Build + GitHub Release + artifact publishing
│ ├── dependabot.yml # Automated dependency updates
│ └── CODEOWNERS # Required reviewers for security-sensitive files
├── CODE_OF_CONDUCT.md # Community expectations and reporting path
├── LICENSE # MIT license text
├── agents.md # Project guidelines for AI coding agents
├── deny.toml # Supply chain policy (licenses, advisories)
├── rust-toolchain.toml # Pinned Rust compiler version
├── SECURITY.md # Vulnerability disclosure policy
└── scanner-data-contract.json # JSON Schema for scan output
cargo build # Debug build
cargo fmt --check # Formatting check
cargo clippy --all-targets -- -D warnings # Lint (must be 0 warnings)
cargo test # Run the full test suite
cargo deny check # License + advisory audit
cargo audit # RustSec vulnerability scan
./scripts/test-scanner.sh # Exercise all CLI subcommands
./scripts/benchmark-scanner.sh # Record repeatable local scan timingsCI runs all of these automatically on every PR. See .github/workflows/ci.yml for the full pipeline.
Set VETTD_TIMINGS=1 when you want per-stage scan timings on stderr during a
local run or benchmark session.
For detailed development instructions: CONTRIBUTING.md For architecture and code walkthrough: docs/architecture.md For public CLI journeys: docs/user-flows.md For the plain-English output spec: docs/output-spec.md For community expectations: CODE_OF_CONDUCT.md For security vulnerability reports: SECURITY.md
| File | Purpose |
|---|---|
~/.config/vettd/config.json |
API key + endpoint (created by vettd auth) |
~/.vettd/.vettd.toml |
Optional access-mode setting (per-user only) |
~/.vettd/scanner_uuid |
Persistent scanner identity (auto-generated) |
~/.vettd/rules/*.toml |
Custom detection rules |
Optional ~/.vettd/.vettd.toml:
[access]
mode = "lite" # limit terminal console findings to the top three artifacts
# search_beta_testing = false # opt into --language, --agent-compatibility,
# # and --rankings beta search filtersBeta search filters:
search_beta_testing = trueenables the--language,--agent-compatibility, and--rankingssearch filters (and switches the directory request to POST with a JSON body). TheSEARCH_BETA_TESTINGenv var (1ortrue) takes precedence and can enable the same behavior without modifying the config file.
Per-user location only. A
.vettd.tomlin a scanned project directory is never consulted — a scanned repo must never be able to self-gate its own findings.--out,--contract,--submit,--json, and--stdoutalways carry the full un-truncated findings regardless of access tier.
Copyright (c) 2026 Agentic Highway.
vettd is licensed under the MIT License. See LICENSE and
COPYRIGHT.