diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 07cdd8a5..53110a78 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -18,7 +18,7 @@ Discovery ──> Scanning ──> Enrichment ──> Blast Radius ──> Compl | Entry point | File | Purpose | |---|---|---| -| CLI | `cli.py` | Click-based CLI with 15+ commands | +| CLI | `cli.py` | Click-based CLI with 22+ commands and groups | | MCP Server | `mcp_server.py` | FastMCP server with 22 tools | | Proxy | `proxy.py` | MCP JSON-RPC proxy with runtime enforcement | | API | `api/server.py` | FastAPI REST server with job queue | @@ -70,10 +70,11 @@ Each module exports `tag_blast_radius(br: BlastRadius)` to annotate findings. │ # Prometheus metrics, JSONL audit trail, webhook alerts ├── runtime/ │ ├── __init__.py # Public exports -│ ├── detectors.py # 6 detectors: ToolDrift, ArgumentAnalyzer, CredentialLeak, -│ │ # RateLimit, SequenceAnalyzer, ResponseInspector +│ ├── detectors.py # 7 detectors: ToolDrift, ArgumentAnalyzer, CredentialLeak, +│ │ # RateLimit, SequenceAnalyzer, ResponseInspector, +│ │ # VectorDBInjectionDetector (RAG/cache-poison, CRITICAL severity) │ └── patterns.py # Regex patterns for credentials, args, cloaking, SVG, Unicode -├── enforcement.py # Tool poisoning detection (10 checks): injection scanning, +├── enforcement.py # Tool poisoning detection (8 checks): injection scanning, │ # inputSchema analysis, capability combos, CVE exposure, │ # drift detection, config analysis, over-permission ├── mcp_introspect.py # Live MCP server connection — tools/list, resources/list, drift @@ -125,8 +126,8 @@ Each module exports `tag_blast_radius(br: BlastRadius)` to annotate findings. ``` ├── api/ │ ├── server.py # FastAPI REST server with job queue -│ ├── auth.py # JWT authentication -│ ├── audit_log.py # API audit logging +│ ├── auth.py # scrypt KDF API keys, RBAC roles (admin/analyst/viewer) +│ ├── audit_log.py # HMAC-SHA256 signed audit log (InMemory + SQLite backends) │ ├── store.py # Base data store abstraction │ ├── postgres_store.py # PostgreSQL backend │ ├── snowflake_store.py # Snowflake backend @@ -213,7 +214,7 @@ cli.py / mcp_server.py / api/server.py | Test functions | 3,419 (3,480 collected by pytest) | | MCP tools | 22 | | Compliance frameworks | 10 | -| Runtime detectors | 6 | +| Runtime detectors | 7 | | Cloud providers | 12 | | SAST CWE mappings | 52 | diff --git a/AUDIT.md b/AUDIT.md index 545c7082..88dd775a 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -451,6 +451,80 @@ ScanRequest → _run_scan_sync() [ThreadPoolExecutor] --- +--- + +## Area 7: CLI (cli.py) + +### Commands verified (22 total) + +`scan`, `inventory`, `validate`, `where`, `check`, `verify`, `history`, `diff`, `policy-template`, `serve`, `api`, `mcp-server`, `completions`, `apply`, `schedule` (group: add/list/remove), `registry` (group: list/search/update/enrich/sync), `proxy`, `guard`, `protect`, `watch`, `analytics`, `dashboard` + +**`serve` vs `api`**: Not duplicates. `serve` = API + bundled Next.js UI, simpler flags. `api` = production server with `--workers`, `--api-key`, `--rate-limit`. Different extras: `[ui]` vs `[api]`. + +**`--introspect`**: Flag on `scan`, wired to `mcp_introspect.py`. Not a standalone command. + +### Fixed in this audit + +| # | File | Fix | +|---|------|-----| +| F13 | `cli.py` | `api` command had no `--log-level` or `--log-json` (inconsistent with `serve`). Added both; `setup_logging()` now called; uvicorn log level wired to user input. | + +### Open issues + +| # | Severity | Issue | +|---|----------|-------| +| O5 | LOW | `guard` command (pre-install CVE check wrapping pip/npm) not mentioned in README. Functional, tested, just undocumented externally. | + +--- + +## Area 8: Discovery + Peripheral Runtime Modules + +### Discovery (discovery/__init__.py) + +- **20 named MCP clients** in `CONFIG_LOCATIONS` (+ `CUSTOM` = 21 `AgentType` enum values). README "20" is accurate. ARCHITECTURE.md "21" also accurate (counts all enum values). No gap. +- `sanitize_env_vars()` called on all env blocks. `validate_path()` used before reading config files. PASS. +- Docker MCP Toolkit handled separately (Docker socket path, not `CONFIG_LOCATIONS`). Correct. + +### Runtime peripheral modules + +| Module | Lines | Wired to CLI | Tests | Status | +|--------|-------|-------------|-------|--------| +| `watch.py` | 304 | `watch` command | `test_watch.py` indirect | PASS | +| `mcp_introspect.py` | 360 | `scan --introspect` | `test_discovery.py` | PASS | +| `enforcement.py` | 759 | `scan` pipeline | `test_enforcement.py` | PASS | + +`enforcement.py`: 8 check functions (`check_cve_exposure`, `check_drift`, `check_claude_config`, `check_agentic_search_risk`, `check_over_permission`, `check_tool_name_collisions` + 2 more). ARCHITECTURE.md previously said "10 checks" — corrected to 8 (F11). + +--- + +## Area 9: Accuracy (ARCHITECTURE.md + SVGs + README) + +### Fixed in this audit + +| # | File | Fix | +|---|------|-----| +| F7 | `ARCHITECTURE.md` | `auth.py — JWT authentication` → `scrypt KDF API keys, RBAC roles (admin/analyst/viewer)`. No JWT anywhere in codebase. | +| F8 | `ARCHITECTURE.md` | `Runtime detectors: 6` → `7` in Module Stats | +| F9 | `ARCHITECTURE.md` | Detector list now includes `VectorDBInjectionDetector` | +| F10 | `ARCHITECTURE.md` | `CLI with 15+ commands` → `22+ commands and groups` | +| F11 | `ARCHITECTURE.md` | `enforcement.py — 10 checks` → `8 checks` | +| F12 | SVGs (7 files) | `6 detectors` → `7 detectors`: engine-internals, modes-flow, offerings-map, scanner-architecture (dark + light variants) | + +### Verified accurate (no changes needed) + +| Claim | Verified | +|-------|---------| +| "20 MCP clients" (README) | ✓ 20 named AgentType values | +| "22 MCP tools" | ✓ meta-test enforces this | +| "10 compliance frameworks" | ✓ 10 tagging modules | +| "52 SAST CWE mappings" | ✓ SAST_CWE_MAP count | +| "12 cloud providers" | ✓ cloud/__init__.py _PROVIDERS | +| OSV as primary vuln source | ✓ | +| scrypt KDF for API keys | ✓ auth.py (n=16384, r=8, p=1) | +| HMAC-SHA256 audit log | ✓ audit_log.py | + +--- + ## Audit Summary (all areas) | Area | Status | Bugs Fixed | Open Issues | @@ -461,6 +535,9 @@ ScanRequest → _run_scan_sync() [ThreadPoolExecutor] | Runtime layer | PASS | 2 (F5-F6) | 0 | | API layer | PASS | 0 | 0 | | Data flow | PASS | 0 | 0 | +| CLI | PASS | 1 (F13) | 1 (O5: guard undocumented) | +| Discovery + peripheral modules | PASS | 0 | 0 | +| Accuracy (ARCHITECTURE + SVGs + README) | PASS | 7 (F7-F12 + F13) | 0 | --- @@ -479,3 +556,6 @@ When re-running this audit, check: - [ ] @mcp.tool count still matches _SERVER_CARD_TOOLS count (both should be 22)? - [ ] Any new compliance frameworks added to scanner but not to ARCHITECTURE.md? - [ ] Databricks security checks: if CIS ever publishes a Databricks benchmark, rename accordingly +- [ ] `guard` command documented in README? (O5) +- [ ] SVG detector count updated if more detectors added? +- [ ] `serve` and `api` commands still aligned on flags as features are added? diff --git a/docs/images/engine-internals-dark.svg b/docs/images/engine-internals-dark.svg index 5c8203b0..f089f32c 100644 --- a/docs/images/engine-internals-dark.svg +++ b/docs/images/engine-internals-dark.svg @@ -207,7 +207,7 @@ RUNTIME (OPTIONAL) - MCP proxy · 6 detectors (drift, injection, credential leak) · config watch · live introspect + MCP proxy · 7 detectors (drift, injection, credential leak, vector DB) · config watch · live introspect diff --git a/docs/images/engine-internals-light.svg b/docs/images/engine-internals-light.svg index 786ff3af..4ab72b13 100644 --- a/docs/images/engine-internals-light.svg +++ b/docs/images/engine-internals-light.svg @@ -207,7 +207,7 @@ RUNTIME (OPTIONAL) - MCP proxy · 6 detectors (drift, injection, credential leak) · config watch · live introspect + MCP proxy · 7 detectors (drift, injection, credential leak, vector DB) · config watch · live introspect diff --git a/docs/images/modes-flow-dark.svg b/docs/images/modes-flow-dark.svg index 6fc5b90d..81ed26ed 100644 --- a/docs/images/modes-flow-dark.svg +++ b/docs/images/modes-flow-dark.svg @@ -75,7 +75,7 @@ PROXY Runtime Proxy agent-bom protect [--mode enforce] - 6 detectors: drift, injection, cred leak + 7 detectors: drift, injection, cred leak, vector DB Policy enforcement on live MCP traffic Replay detection + sequence analysis Prometheus metrics · JSONL audit log diff --git a/docs/images/modes-flow-light.svg b/docs/images/modes-flow-light.svg index d4cf01ba..91aabf61 100644 --- a/docs/images/modes-flow-light.svg +++ b/docs/images/modes-flow-light.svg @@ -75,7 +75,7 @@ PROXY Runtime Proxy agent-bom protect [--mode enforce] - 6 detectors: drift, injection, cred leak + 7 detectors: drift, injection, cred leak, vector DB Policy enforcement on live MCP traffic Replay detection + sequence analysis Prometheus metrics · JSONL audit log diff --git a/docs/images/offerings-map-dark.svg b/docs/images/offerings-map-dark.svg index 48527076..90344462 100644 --- a/docs/images/offerings-map-dark.svg +++ b/docs/images/offerings-map-dark.svg @@ -93,7 +93,7 @@ Runtime Proxy MCP traffic monitoring - 6 detectors + alert webhook + 7 detectors + alert webhook One engine, multiple deployment modes diff --git a/docs/images/offerings-map-light.svg b/docs/images/offerings-map-light.svg index 88e56f2c..21ff5d4f 100644 --- a/docs/images/offerings-map-light.svg +++ b/docs/images/offerings-map-light.svg @@ -93,7 +93,7 @@ Runtime Proxy MCP traffic monitoring - 6 detectors + alert webhook + 7 detectors + alert webhook One engine, multiple deployment modes diff --git a/docs/images/scanner-architecture-dark.svg b/docs/images/scanner-architecture-dark.svg index 1b6f9e5c..bfe03ae2 100644 --- a/docs/images/scanner-architecture-dark.svg +++ b/docs/images/scanner-architecture-dark.svg @@ -154,7 +154,7 @@ Runtime Protection - MCP Stdio Proxy · 4 inline scanners · 6 detectors · Fleet mgmt · Trust score · Alert pipeline + MCP Stdio Proxy · 4 inline scanners · 7 detectors · Fleet mgmt · Trust score · Alert pipeline diff --git a/docs/images/scanner-architecture-light.svg b/docs/images/scanner-architecture-light.svg index cb25c9cd..fadb3994 100644 --- a/docs/images/scanner-architecture-light.svg +++ b/docs/images/scanner-architecture-light.svg @@ -154,7 +154,7 @@ Runtime Protection - MCP Stdio Proxy · 4 inline scanners · 6 detectors · Fleet mgmt · Trust score · Alert pipeline + MCP Stdio Proxy · 4 inline scanners · 7 detectors · Fleet mgmt · Trust score · Alert pipeline diff --git a/src/agent_bom/cli.py b/src/agent_bom/cli.py index a9592ce7..46a25dd5 100644 --- a/src/agent_bom/cli.py +++ b/src/agent_bom/cli.py @@ -3662,6 +3662,15 @@ def serve_cmd(host: str, port: int, persist: Optional[str], cors_allow_all: bool metavar="DB_PATH", help="Enable persistent job storage via SQLite (e.g. --persist jobs.db). Jobs survive restarts.", ) +@click.option( + "--log-level", + "log_level", + type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR"], case_sensitive=False), + default="INFO", + show_default=True, + help="Log verbosity level.", +) +@click.option("--log-json", "log_json", is_flag=True, help="Emit structured JSON logs (for log aggregation pipelines).") def api_cmd( host: str, port: int, @@ -3672,6 +3681,8 @@ def api_cmd( api_key: str | None, rate_limit_rpm: int, persist: str | None, + log_level: str, + log_json: bool, ): """Start the agent-bom REST API server. @@ -3696,6 +3707,10 @@ def api_cmd( agent-bom api --port 9000 # custom port agent-bom api --reload # dev mode """ + from agent_bom.logging_config import setup_logging + + setup_logging(level=log_level, json_output=log_json) + try: import uvicorn except ImportError: @@ -3746,7 +3761,7 @@ def api_cmd( port=port, reload=reload, workers=1 if reload else workers, - log_level="info", + log_level=log_level.lower(), )