This release includes 1 security fix for security teams reviewing exposed deployments.
Affected surfaces
Summary
AI summarycheck_dependencies mode parameter removal (online, offline) enforces privacy‑by‑default behavior.
Full changelog
The dependency scanner now uses a govulncheck-style privacy model: it bulk-downloads the public OSV Go vulnerability snapshot once and intersects locally against go.mod. Module names (private or public) are no longer sent to OSV.dev. The only outbound request is a generic GET on the public snapshot URL at storage.googleapis.com/osv-vulnerabilities/Go/all.zip, indistinguishable from any other govulncheck consumer.
BREAKING
check_dependencies mode parameter: online and offline keywords removed. Only auto (default) is supported. Callers passing the removed values now receive an explicit migration error pointing to docs/check_dependencies.md and this CHANGELOG. Pre-stable BREAKING; no deprecation shims, since the previous keywords were the privacy-leak vector.
Highlights
Privacy
- Zero outbound to
api.osv.devduring any scan. The QueryBatch path that POSTed module names is gone. - Cache directory resolution chain:
PCI_MCP_CACHE_DIR->XDG_CACHE_HOME/pci-dss-mcp/vuln-cache->$HOME/.pci-dss-mcp/vuln-cache->os.UserCacheDir/pci-dss-mcp/vuln-cache-> hard-fail. CWD-relative fallback removed. Existing users at$HOME/.pci-dss-mcpcontinue to work without migration. - New env var
OSV_BASE_URLfor enterprise self-hosted OSV mirrors. Default unchanged.
HTTP cache lifecycle
- 0-24h fresh tier: zero outbound, read directly from disk.
- 24h-7d: conditional GET via
If-None-MatchandIf-Modified-Since(304 Not Modified = revalidate, near-zero bytes). - Greater than 7d: force-refresh.
- Cross-process file lock via
gofrs/flockprevents parallel-scan races and cache corruption during refresh. - New INFO findings emit only on actual fallback paths:
DEP-CACHE-COLD(cache absent + network refresh failed),DEP-CACHE-STALE(stale fallback used because network refresh failed),DEP-CACHE-NO-DIR(no writable cache directory found in resolution chain). The previous file-age-based STALE emit on every >7d cache was removed.
Removed (Internal)
scanner/depscanner.OSVClient.QueryBatch()deleted, along withQueryBatchRequest,QueryBatchResponse,Query,QueryPackage,VulnRef,QueryResulttypes.scanner/depscanner.scanOnline()andscanner/depscanner.scanAuto()consolidated into the cache-ensure path.- The
defaultOSVBaseURLconstant retained for the single-vulnFetchVulnpath.
Migration
For callers of check_dependencies and the wrapper tools (generate_compliance_report / triage_findings dep_scan_mode):
mode="online": replace withmode="auto"(or omitmode, default isauto). Behavior change: privacy by default. First scan downloads ~8MB cache.mode="offline": replace withmode="auto". The TTL-driven cache covers the air-gapped use case. Bind-mount$HOME/.pci-dss-mcpinto the container or setPCI_MCP_CACHE_DIRto an air-gap-allowed path. Runupdate_vulnerability_dbonce with network access to bootstrap. Seedocs/check_dependencies.mdfor the canonical bind-mount pattern.
Verification
| Gate | Result |
|------|--------|
| make vet | PASS |
| make test (race, all packages) | PASS |
| make test-fixture (golden regression) | PASS |
| Behavioral parity vs v0.6.2 (violation table on golden fixture) | PASS (only rules_coverage.depscanner extension; violation rows unchanged) |
| Live-path vs fixture-copy smoke parity (49 CRITICAL / 89 HIGH / 27 MEDIUM / 0 LOW / 59 INFO) | PASS |
| G6 manual smoke (tcpdump observation): zero packets to api.osv.dev on cold and warm cache | PASS |
| G7 manual smoke (Docker bind-mount UX): host-side cache persists across --rm runs, mtime stable on warm path, ephemeral when no bind-mount | PASS |
| TestQueryBatchSymbolDeleted (reflection-based privacy regression gate) | PASS |
| TestNetTrafficZeroQueryBatch (records every outbound during fixture scan, asserts zero module-name fragments leak via body or URL) | PASS |
| TestCacheLifecycle (8 subtests: cache_hit_fresh, cache_miss_cold, revalidate_304, revalidate_200, force_refresh_gt7d, corrupted_cache, parallel_cold_cache, stale_fallback_network_failed) | PASS |
| TestAirGappedScan (cold_cache_no_network, no_writable_dir) | PASS |
| TestOSVBaseURLOverride (env-var trust boundary) | PASS |
Severity counts on testdata/vulnerable-payment-service remain byte-identical to v0.6.2: 49 CRITICAL / 89 HIGH / 27 MEDIUM / 0 LOW / 59 INFO. No detection logic changed for any other scanner.
Distribution
go install github.com/shyshlakov/[email protected]- Multi-arch Docker (linux/amd64 + linux/arm64), cosign-signed via OIDC:
ghcr.io/shyshlakov/pci-dss-mcp:0.6.3and:latest - MCP Registry:
io.github.shyshlakov/pci-dss-mcpv0.6.3 (auto-published on tag)
Pull request
Merged via #25.
Breaking Changes
- `check_dependencies` `mode` parameter: removal of `online` and `offline` keywords; only `auto` (default) is supported.
Security Fixes
- Eliminated privacy leak: module names are no longer sent to `api.osv.dev`; only a generic GET of the public snapshot is performed.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About shyshlakov/pci-dss-mcp
PCI DSS v4.0.1 static-analysis MCP server for Go payment codebases. 12 scanners detect PAN/CVV exposure, weak crypto, missing audit logs, vulnerable deps, TLS misconfig, auth weaknesses, plus CycloneDX 1.6 SBOM generation - each finding mapped to the exact PCI requirement. AI-assisted triage via triage_findings. Keyless-signed multi-arch Docker image on ghcr.io.
Related context
Beta — feedback welcome: [email protected]