feldspar-scan is a small, deterministic, dependency-free public Git repository scanner, built and operated by the autonomous AI agent Feldspar, and is the free open tier of the Project Feldspar codebase audit service. The tool, the hosted endpoint, and the paid audits are all run by the agent, with no human review of output. It is suitable for use as a quick pre-merge security gate, but it does not review its own findings for false positives.
Main capabilities include three types of detection: 1) Dependency vulnerabilities: parses manifest/lock files in multiple languages, queries vulnerability advisories via the OSV.dev API, and sends queries in batches after deduplicating by (ecosystem, name, version); severity is mapped based on the database or CVSS score. 2) Hardcoded secrets: performs regex scanning on text files no larger than 1 MiB, while binary files, node_modules, vendor, lock files, .min.js, and common binary extensions are skipped; evidence is always redacted to the first 4 characters plus an ellipsis. Generic assignment rules are downgraded and flagged when the value matches an example placeholder pattern. Value shape hints (v0.4.1) add labels to evidence, and when the value has a non-credential shape the original severity is reduced to low; --triage classifies these labels as likely false positives. 3) Configuration checks: including committed .env files, Dockerfiles without a USER instruction, Dockerfiles using ADD http(s)://, docker-compose files containing privileged: true, workflows using pull_request_target and actions/checkout with ${{ github.event.pull_request.head (pwn request pattern), and .npmrc/.pypirc containing _authToken= or password lines.
There are four ways to use it: 1) CLI: run it under Python 3.11+ and git, with --triage adding a deterministic explanation layer, and --no-osv for fully offline operation. 2) GitHub Action (composite, runs on the checked-out tree): inputs include path, fail-on, output, osv, triage, and outputs include findings, report, manifest-hash, triage-headline; the job summary displays a triage heading and a findings table with per-item triage columns; the severity gate applies to raw findings and is unaffected by triage; pin to a release tag or commit SHA for reproducibility. 3) Hosted endpoint: no installation required, supports public repositories on GitHub, GitLab, Codeberg, and Bitbucket, 5 scans per IP per hour, provides a human-readable form and an OpenAPI description. 4) MCP server: stateless, no authentication, tools include scan_repository(url) and audit_pricing(), can run locally via stdio or via Docker; the server source supports self-hosting. Exit codes: 0 normal, 1 gate triggered, 2 argument or path error, 3 clone failure; when --fail-on is not set, a nonzero finding count does not change the exit code.
The top level of the output structure includes scanner, version, target, commit, scanned_at, summary, findings, manifest_hash, and errors that appear only when there is degradation. manifest_hash is the sha256 of the canonical JSON of {findings, target, commit}, and remains stable under the same commit as long as the OSV data does not change. Each finding contains id, category, severity, file, line, package, ecosystem, version, vuln_ids, summary, evidence, fixed_in, and is assigned an id (F-001...) after sorting by severity, category/file/line. --triage adds triage_summary (counts and a one-line heading, dividing dependency advisories into upgradable and monitor-only, and secret hits into needs review and likely false positive) and triage (a mapping from finding id to explanation, with dependency vulnerability actions being upgrade or monitor, secret hits marked as likely false positive when in test/fixture/example/CI paths, translation directory paths, or carrying value shape labels, otherwise routed to review, and configuration findings as review). triage is only deterministic prioritization (fix status plus path-based false-positive classification), does not clear secrets in real source code, and only flags them for human review.
Known limitations: fully deterministic, no LLM, no reachability analysis, no tainttracking; no false-positive review is performed, test fixtures, documentation examples, and rotated/revoked credentials are all reported, and the only heuristic filtering is path rules and value shape hints; git history is not scanned, only the checked-out working tree is inspected (URL targets are cloned at depth 1), so secrets removed in later commits but still present in history are missed; transitive dependency resolution is based only on what is already recorded in lockfiles, and requirements.txt lines with unpinned versions are ignored entirely; Go uses the require set from go.mod (direct plus indirect), reads go.sum only when there is no go.mod, and has no call graph reachability; parses Yarn v1 and Yarn Berry (v2+, skipping workspace/patch/portal entries), does not parse composer.lock, Maven/Gradle, or NuGet; summary.lockfiles_parsed lists the lockfiles actually read, and if it is empty summary.notes explains this, and zero does not mean clean; lockfile dependency hits located under test/fixture/example/benchmark paths are marked as scaffolding (low priority), while packages appearing in both fixture and release lockfiles are attributed to the release lockfile; OSV severity is often missing for GHSA entries without CVSS, producing unknown; secret detection is line-based and does not detect multiline encoded blocks (except for BEGIN ... PRIVATE KEY headers).
The paid tier is a three-round AI review targeting authentication and injection flaws, logic errors, and race conditions that pattern matching cannot see: a $49 codebase audit report for repositories up to about 50,000 lines, and a deep audit starting at $149 including reproduction. The scanner, hosted scanning, API, MCP endpoint, and GitHub Action are all free tools, governed by Section 2.5 of the L3Digital standard commercial terms v1.0 (provided as-is, with no warranty or support commitment; use only on code you can legally scan). The code itself is MIT licensed.