agent-bom is a read-only security scanner. This document is an explicit, auditable contract of what the tool accesses — and what it never touches.
agent-bom reads only what you explicitly ask it to scan:
| Target | How specified | What is read |
|---|---|---|
| Agent configs | auto-discovery or --project |
Config JSON/YAML files (e.g. claude_desktop_config.json) |
| Inventory | --inventory |
Your inventory JSON file |
| Lock files | inferred from project | package-lock.json, requirements.txt, Cargo.lock, etc. |
| Docker images | --image |
Image filesystem layers (via container inspection subprocess) |
| Kubernetes | --k8s |
Pod specs via kubectl get pods -o json (read-only) |
| Terraform | --tf-dir |
.tf source files (no state files, no .tfvars) |
| GitHub Actions | --gha |
.github/workflows/*.yml files |
| SBOM files | --sbom |
CycloneDX/SPDX JSON you provide |
Auto-discovery reads these specific config paths only. No directory traversal, no glob patterns, no recursive walks. If a file does not exist, it is silently skipped.
| Client | macOS path | Linux path |
|---|---|---|
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
~/.config/Claude/claude_desktop_config.json |
| Claude Code | ~/.claude/settings.json, ~/.claude.json |
same |
| Cursor | ~/Library/Application Support/Cursor/User/globalStorage/cursor.mcp/mcp.json, ~/.cursor/mcp.json |
~/.config/Cursor/User/globalStorage/cursor.mcp/mcp.json, ~/.cursor/mcp.json |
| Windsurf | ~/.windsurf/mcp.json, ~/Library/Application Support/Windsurf/User/globalStorage/windsurf.mcp/mcp.json |
~/.windsurf/mcp.json |
| Cline (VS Code) | ~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json |
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json |
| VS Code Copilot | ~/Library/Application Support/Code/User/mcp.json |
~/.config/Code/User/mcp.json |
| Continue.dev | ~/.continue/config.json |
same |
| Zed | ~/.config/zed/settings.json |
same |
| OpenClaw | ~/.openclaw/openclaw.json |
same |
| Cortex Code | ~/.snowflake/cortex/mcp.json |
same |
| Docker MCP Toolkit | ~/.docker/mcp/registry.yaml, ~/.docker/mcp/catalogs/docker-mcp.yaml |
same |
.mcp.jsonmcp.json.cursor/mcp.json.vscode/mcp.json.openclaw/openclaw.json
docker-compose.ymldocker-compose.yamlcompose.ymlcompose.yaml
Total: 27 specific file paths. No other files are ever read during auto-discovery.
Use --dry-run to preview exactly which paths would be read before any scan runs.
From each MCP client config, agent-bom extracts:
| Data element | Example | Used for |
|---|---|---|
| Server name | "filesystem" |
Inventory labeling |
| Command | "npx" |
Package identification |
| Arguments | ["@modelcontextprotocol/server-filesystem", "/path"] |
Package name + version extraction |
| Env var names | "OPENAI_API_KEY" |
Credential exposure mapping |
- Environment variable values — only names are read, never values
- File path arguments — shown in inventory but never traversed or opened
- Config file contents — only the structured server definitions are parsed
Env var names matching these patterns are flagged as credential-like:
Flagged: *KEY*, *TOKEN*, *SECRET*, *PASSWORD*, *CREDENTIAL*, *API_KEY*, *APIKEY*, *AUTH*, *PRIVATE*, *CONNECTION*, *CONN_STR*, *DATABASE_URL*, *DB_URL*
Excluded (standard system vars): PATH, HOME, LANG, SHELL, USER, TERM, EDITOR, DISPLAY, PWD, TMPDIR
Credential values are never read, stored, logged, or transmitted. Only names appear in reports as blast-radius indicators.
- Never write to any config file, lock file, or project file
- Never execute MCP servers or agent processes
- Never store credential values — only env var names appear in reports
- Never transmit your file contents, project structure, or inventory to external services
- Never cache any personal data to disk (scan history is opt-in via
--save) - Never require authentication tokens or API keys (NVD key is optional for rate limits only)
- Never access arbitrary files — only the 27 enumerated paths above
- Never traverse directories or use glob patterns during auto-discovery
- Never run background processes, daemons, cron jobs, or system services
All network calls are read-only GET/POST to public vulnerability databases. Only package names and versions are sent. No user data is included in requests.
| Service | URL | What we send | What we receive | Auth |
|---|---|---|---|---|
| OSV.dev | https://api.osv.dev/v1/querybatch |
Package names + versions | CVE IDs, advisories | None |
| NVD/NIST | https://services.nvd.nist.gov/rest/json/cves/2.0 |
CVE IDs | CVSS scores, CWE IDs | Optional (NVD_API_KEY for higher rate limits) |
| FIRST EPSS | https://api.first.org/data/v1/epss |
CVE IDs | Exploit probability scores | None |
| CISA KEV | https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json |
(none — full download) | KEV catalog | None |
| npm registry | https://registry.npmjs.org/{pkg}/{version} |
Package name + version | Package metadata | None |
| PyPI | https://pypi.org/pypi/{pkg}/{version}/json |
Package name + version | Package metadata | None |
| OpenSSF Scorecard | https://api.securityscorecards.dev/projects/github.com/{owner}/{repo} |
GitHub owner/repo | Scorecard scores | None |
| Jira (optional) | https://{instance}.atlassian.net/rest/api/3/issue |
Finding summaries | Ticket confirmation | API token (--jira-token) |
| Slack (optional) | User-provided webhook URL | Finding summaries | Delivery status | Webhook URL (--slack-webhook) |
| Vanta (optional) | https://api.vanta.com/v1/ |
Compliance evidence | Upload confirmation | API token (--vanta-token) |
| Drata (optional) | https://public-api.drata.com/ |
Compliance evidence | Upload confirmation | API token (--drata-token) |
[Local config files] → extract server name, command, args, env var NAMES
↓
[Package names+versions] → sent to OSV.dev, NVD, EPSS, KEV, npm, PyPI, OpenSSF Scorecard
↓
[Findings (optional)] → sent to Jira, Slack, Vanta, Drata (only if flags provided)
↓
[CVE results] → returned to local process, written to stdout or --output file
- Sent to APIs: package name + version only (e.g.,
express@4.17.1) - Returned from APIs: CVE IDs, severity scores, advisory URLs
- Never sent: file paths, config contents, env var values, scan results, hostnames, IP addresses
All external calls can be completely disabled with --no-scan (inventory-only mode).
No telemetry, analytics, or tracking. Zero network calls unless scanning for vulnerabilities.
Environment variables in MCP server configs are never read for their values.
Only the key names (e.g. OPENAI_API_KEY, DATABASE_URL) are inspected to
determine whether credentials are present. Values are always shown as ***REDACTED***.
agent-bom itself optionally uses one env var:
NVD_API_KEY— increases NVD rate limit from 5 to 50 requests per 30 seconds. This key is sent only toservices.nvd.nist.govand is never logged, cached, or transmitted elsewhere.
Users can restrict or bypass auto-discovery entirely:
| Flag | Effect |
|---|---|
--dry-run |
Shows exactly which files, APIs, and data would be accessed, then exits without reading anything |
--inventory <file> |
Scans only the agents/packages defined in a JSON inventory file — skips all config discovery |
--project <dir> |
Scans only MCP configs in a specific project directory |
--config-dir <dir> |
Reads MCP configs from a single custom directory only |
--no-skill |
Disables skill/instruction file scanning |
--skill-only |
Runs only skill scanning, skips all agent/package/CVE analysis |
--no-scan |
Inventory-only mode — discovers configs but makes no network calls |
Recommended first run: agent-bom agents --dry-run to preview the complete access plan before any actual scanning.
This is an open-source tool — you can verify every claim above:
When running agent-bom api, the HTTP server adds these headers to every response:
X-Agent-Bom-Read-Only: true
X-Agent-Bom-No-Credential-Storage: true
The API server itself runs entirely in-process. It does not make third-party outbound
connections unless a scan job explicitly requests enrichment ("enrich": true in the
request body). Browser clients and local dashboards may still connect to the local
agent-bom API over HTTP/WebSocket for normal UI operation.
agent-bom never stores, logs, or transmits credentials. All authentication follows the principle of least privilege with read-only scopes.
| Provider | Preferred auth | Fallback | What we read |
|---|---|---|---|
| Snowflake | SSO via externalbrowser (Okta/Azure AD/Google) — default |
Key-pair (SNOWFLAKE_PRIVATE_KEY_PATH) for CI/CD |
Read-only SQL on ACCOUNT_USAGE |
| Databricks | SDK credential chain: ~/.databrickscfg OAuth profile or workload identity |
DATABRICKS_TOKEN PAT env |
Read-only cluster/library listing |
| AWS | IAM role / OIDC workload identity (GitHub Actions) / ~/.aws/credentials profile |
AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY env |
Read-only: Describe*, List*, Get* |
| Azure | Managed identity / az login / service principal |
AZURE_CLIENT_SECRET env |
Read-only resource listing |
| GCP | Application Default Credentials / workload identity | GOOGLE_APPLICATION_CREDENTIALS env |
Read-only resource listing |
| HuggingFace | HF_TOKEN env (read-only scope) — optional, public models need nothing |
None | Model metadata via Hub API |
| NVD | NVD_API_KEY env — optional, only increases rate limits |
None (public API) | CVE data only |
# Preferred: SSO (default — opens browser for Okta/Azure AD/Google)
agent-bom agents --snowflake
# Key-pair auth (recommended for CI/CD — no browser needed)
SNOWFLAKE_PRIVATE_KEY_PATH=~/.ssh/snowflake_key.p8 \
agent-bom agents --snowflake
# Explicit SSO
agent-bom agents --snowflake --snowflake-authenticator externalbrowser
# OAuth access token
SNOWFLAKE_AUTHENTICATOR=oauth SNOWFLAKE_TOKEN=<token> \
agent-bom agents --snowflake
# OAuth token
SNOWFLAKE_TOKEN=<token> \
agent-bom agents --snowflake --snowflake-authenticator oauth| Principle | How agent-bom upholds it |
|---|---|
| Confidentiality | Credentials pass env → SDK, never logged. sanitize_error() strips secrets from all error messages. Audit logs stored at 0600 permissions. |
| Integrity | SHA-256 payload hashing on every proxied MCP call. Audit logs HMAC-signed (SHA-256) for tamper detection. Set AGENT_BOM_AUDIT_HMAC_KEY in production to persist verifiability across restarts. Model weight hash verification (--verify-model-hashes). SBOM + VEX support for supply chain integrity. |
| Availability | Graceful degradation on auth failure (warning, not crash). Offline mode (--no-scan). Rate limiting respected — we never exhaust API quotas. |
- Never write to any cloud resource (pure read-only)
- Never cache credentials to disk
- Never log credential values (sanitize_error removes them)
- Never require admin/write permissions
- Never make third-party network calls beyond the explicitly listed data sources. Local UI-to-API traffic is expected when using the dashboard or browser client.
See SECURITY.md for responsible disclosure via GitHub Security Advisories.