What's new
A version-by-version history of Fendix. v3.7.0 shipped October 2026: the GitHub Action fails the job when Semgrep cannot run, and a fatal Semgrep run is recorded as failed instead of passing as a clean scan. Each entry below lists what changed in that release.
Patch — install.sh `mkdir -p` fix
May 1, 2026
- Critical install-pipe fix.
scripts/install.shnowmkdir -pthe install directory before themv. Previously,curl -fsSL https://get.fendix.dev/install.sh | FENDIX_DIR=$HOME/.local/bin shfailed on any system where$HOME/.local/bindidn't pre-exist withmv: cannot move 'fendix' to '/home/runner/.local/bin/fendix': No such file or directory. Blocked the benchmark CI on every run and broke any first-time user who setFENDIX_DIRto a non-existent dir. The fix triesmkdir -pnon-sudo first, falling back tosudo mkdir -ponly when a parent up the chain isn't writable — POSIX-sh clean. Mirrored toget.fendix.dev/install.shautomatically by the release pipeline's mirror-sync job - `fendix init` zero-config workflow generator. New
fendix initsubcommand detects the project's stack (Go viago.mod, Python viapyproject.toml/requirements.txt/setup.py/Pipfile, Node.js, Ruby, Rust, Java/Kotlin, PHP) plus a colocated OpenAPI/Swagger spec at any of 14 conventional paths. Writes.github/workflows/fendix.yml(drop-in PR-gated DAST + SAST scan, embedded viago:embed) plus.fendix-ignore(commented starter for finding-level suppressions). Refuses to overwrite by default;--forceoverrides;--printdry-runs to stdout. Note:fendix initwas later extended to also write.fendix.yaml— see the v0.7.0 entry - README repositioned around correlated evidence. Hero moved beyond generic scanner positioning to explain how Fendix combines DAST and SAST evidence in one PR check. The release also added clearer trust signals for the single binary, signed releases, and telemetry-free execution.
- 'What Fendix sends to the network' section at top of README. Five-row table covering default scan / active probing / white-box / no-flags / telemetry. Explicit 'no telemetry code; verify with tcpdump' claim. Plus a 'Verifying signed releases' section with the full cosign keyless verify recipe
- Vulnerable-app benchmark scaffold. New
scripts/benchmark/run-juice-shop.sh+make benchmark+.github/workflows/benchmark.yml(workflow_dispatchonly) +docs/benchmarks.md. CI workflow installs Fendix viahttps://get.fendix.dev/install.sh(doubles as install-pipe smoke test). Real juice-shop numbers captured in the v0.7.0 entry
First Stable Signed Release
April 30, 2026
- First stable signed release. Every binary,
.deb,.rpm, and Docker manifest ships with.crt+.sigcosign sidecars verifiable against the build's GitHub Actions OIDC identity — no static public key, no rotation surface, no key-loss recovery story - Cosign keyless signing fully active on the release pipeline (Sigstore Fulcio + GitHub Actions OIDC).
COSIGN_ENABLED=trueflipped on the engine repo on 2026-04-30T14:07Z; rc2 was the first tag to exercise the full signed-release path end-to-end, then promoted to v0.6.0 final after pipeline validation. Cosign steps hard-fail the release job, so a broken signing path can't silently ship unsigned artifacts https://get.fendix.dev/install.shis live — DNS CNAME at the registrar, GitHub Pages on the homebrew-fendix mirror, auto-provisioned Let's Encrypt cert. End-to-end smoke test verified the install pipe end-to-end. Mirror URL retained as a documented fallback. Engine repo is now the single source of truth for everything served at get.fendix.dev — auto-synced byrelease.ymlon everyv*tag- Linux arm64 release binary added —
brew install fendixandcurl -fsSL https://get.fendix.dev/install.sh | shnow serve native ARM builds for Graviton, Ampere, Raspberry Pi, and ARM Linux laptops - Multi-arch Docker image at
ghcr.io/abdel-rahmansaied/fendix:vX.Y.Z— manifest list coverslinux/amd64+linux/arm64;docker pullpicks the right arch automatically - Linux
.deband.rpmpackages built via nfpm — install withsudo dpkg -i fendix-*.deb && sudo apt-get install -forsudo dnf install ./fendix-*.rpm. Declarespython3as required andsemgrepas recommended - Documentation pass for external evaluators: 5-minute juice-shop walkthrough (
docs/walkthrough-juice-shop.md), Semgrep rule-author guide (docs/semgrep-rules.md), triage workflow (docs/triage-workflow.md), JSON schema reference (docs/schema.md), all cross-linked from a top-level Documentation index in the README - New
--debug-bundle <path>flag writes a redacted diagnostic.tar.gzfor attaching to bug reports — auth values masked as[REDACTED], full DEBUG slog stream tee'd into the bundle, probe audit log on--enable-active. Auth credentials never leak (e2e regression locks this in) SECURITY.md+ active-scanner threat model (docs/threat-model.md): vulnerability disclosure policy, supported-versions, cosign verification instructions, and the 7-threat safety envelope every active probe must maintain- Performance benchmark suite: scan time vs endpoint count, peak goroutine count, allocation profile — published in README. Reference: 1000 endpoints in 31.7 ms / 24.7 MB / 166 peak goroutines (Apple M1, Go 1.21)
External Release Readiness
April 30, 2026
- Linux arm64 release binary added —
brew install fendixandcurl -fsSL .../install.sh | shnow serve native ARM builds for Graviton, Ampere, Raspberry Pi, and ARM Linux laptops - Multi-arch Docker image at
ghcr.io/abdel-rahmansaied/fendix:vX.Y.Z— manifest list coverslinux/amd64+linux/arm64;docker pullpicks the right arch automatically - Cosign keyless signing wired (Sigstore Fulcio + GitHub Actions OIDC; opt-in via the
COSIGN_ENABLED=truerepo variable). When enabled, every binary ships with.sig+.crtsidecar files - Linux
.deband.rpmpackages built via nfpm — install withsudo dpkg -i fendix-*.deb && sudo apt-get install -forsudo dnf install ./fendix-*.rpm. Declarespython3as required andsemgrepas recommended - New
docs/install.mdinstall reference covers every install path with cosign verification one-liners;get.fendix.devshort-URL installer planned (operator-action: domain registration + GitHub Pages CNAME) - Documentation pass for external evaluators: 5-minute juice-shop walkthrough (
docs/walkthrough-juice-shop.md), Semgrep rule-author guide (docs/semgrep-rules.md), triage workflow (docs/triage-workflow.md), JSON schema reference (docs/schema.md), all cross-linked from a top-level Documentation index in the README - New
--debug-bundle <path>flag writes a redacted diagnostic.tar.gzfor attaching to bug reports — auth values masked as[REDACTED], full DEBUG slog stream tee'd into the bundle, probe audit log on--enable-active. Auth credentials never leak (e2e regression locks this in) SECURITY.md+ active-scanner threat model (docs/threat-model.md): vulnerability disclosure policy, supported-versions, cosign verification instructions, and the 7-threat safety envelope every active probe must maintain- Performance benchmark suite: scan time vs endpoint count, peak goroutine count, allocation profile — published in README. Reference: 1000 endpoints in 31.7 ms / 24.7 MB / 166 peak goroutines (Apple M1, Go 1.21)
- Release-candidate cut to validate the new pipeline (cosign + nfpm + ghcr) end-to-end before tagging clean v0.6.0; signed-release validation pending
COSIGN_ENABLED=true
Quality & Ops
April 30, 2026
- Public JSON output schema published (
docs/schema.md+docs/schema.jsondraft-07); validator runs in tests against every emitted report;findings: []instead ofnullwhen empty - Path-parameter substitution: templated endpoints like
/users/{id}now scan against/users/1(or schema-derived sample). Resolution order:schema.example→schema.enum[0]→ type-driven default → name heuristic → fallback1. Endpoint.Path stays templated for reports; FullURL is concrete - Logging hygiene: aggregated WARN volume — max 3 per check key per scan, rest downgraded to DEBUG. New
INFO warning summaryline at scan end. Real-world: 30 WARN lines → 9 + 1 summary on a 10-endpoint scan against an unreachable target - Scan budgets: new
--max-requests(soft cap on total HTTP requests; discovery exempt),--max-duration(Go duration string, e.g.5m),--respect-robots(treat robots.txt Disallow as hard restriction across all discovery sources) - New auth profile:
--auth-type apikey-queryputs the credential in the URL query string instead of a header — common for legacy/sensor APIs that prefer query placement - Auth profiles end-to-end: bearer / apikey-header / apikey-query / basic / cookie all covered by e2e tests that record what reaches the server
- Concurrency review: race-clean proof at 1000 endpoints × 32 workers under
go test -race; newFuzzWorkerPool_CancelTimingfuzzer (4455 execs / zero failures over 15s of fuzzing) - Severity↔confidence consistency enforced — LOW confidence caps severity at MEDIUM, MEDIUM caps at HIGH (matches the scoring formula's implicit max). Inconsistent findings get severity downgraded with an aggregated WARN line
- Drop-in GitHub Actions workflow:
examples/github-actions/fendix-scan.ymldoes scan →actions/cachebaseline → SARIF upload → PR summary comment viaactions/github-script@v7
Coverage Parity
April 29, 2026
- Correlator finalized: HTTP method-prefix stripping + path-suffix matching (handles base-path skew like spec
/pet/findByStatus↔ live/api/v3/pet/findByStatus); debug instrumentation withmatch_kind=exact|suffix|fuzzy; blackbox findings consumed at most once - Real CVE coverage: pip-audit (PyPI) + npm audit (JS) + govulncheck (Go) as primary paths; hardcoded list as offline fallback. Real-world: badcode/requirements.txt = 6 deps findings (offline) → 97 with pip-audit installed (16× coverage)
- Go module support —
go.modfiles now scanned by govulncheck; only emits findings on actually-called code paths (vendored-but-uncalled noise dropped) - Crawler upgrade: robots.txt + sitemap.xml + HTML link parsing with recursive depth. Real-world: httpbin.org discovery went from 1 endpoint to 3 (Disallow /deny + linked /forms/post + brute-force /robots.txt)
- New flags:
--wordlist,--crawl-depth(default 1),--max-endpoints(default 500); built-inCommonPathsexpanded ~50 → 117 with admin/dashboard/source-control/DevOps tooling paths - Findings deduplication: identical issues across N endpoints collapse into one finding with
affected_endpoints(real-world: petstore 160 → 10, 16× reduction) - Static analyzer: 6 new patterns — pickle.load, yaml.load without SafeLoader, MD5/SHA1 for passwords, open redirect, SSRF, auth-header trust
- Multi-step SQLi detection via intra-function scope tracking (
sql = '...' + var; cursor.execute(sql)) - Active scanner: body & header param probing; error-based + boolean-based SQLi; SQLite + Oracle time-based payloads (5 DB types total)
- New
--max-probes-per-endpointflag (default 20) for active scan budget control - Secrets analyzer: 8 new provider patterns — GitHub, Stripe, Slack, Google, Anthropic, OpenAI, npm, GCP service-account JSON (15 total, was 7)
- .env file scanning fixed (dotfile walker now yields env-files; unquoted KEY=value pattern gated to .env*)
- v0.4.0 ships the planned v0.3.0 batch under a single tag
P0 Flag Wiring
April 29, 2026
--save-baselinenow actually writes a file (was previously a silent no-op at the CLI)--code-only scans run successfully (orchestrator no longer early-exits when only --code is given)- Active scanner now uses spec-defined query/path parameters instead of hardcoded
id --specnow acceptshttps://...URLs in addition to local file paths (fetched with content-type detection, 50 MB cap)- SARIF rule IDs are now stable per check type (
fendix.<category>.<title-slug>) — breaking change for v0.1 SARIF baseline consumers - End-to-end test infrastructure: every CLI flag now has a test that runs the binary and asserts observable effect
Initial Release
April 2026
- Initial production release — ~594 tests across the engine
- MIT License, CHANGELOG, .fendix-ignore.example template
- Ready for production use with full documentation
Hardening
April 2026
- Performance benchmark suite across all critical paths
- Go native fuzz testing (362k+ executions, 0 panics)
- Python hypothesis fuzz testing — found and fixed 3 real bugs
- Self-audit: 0 production code vulnerabilities
- 29 resilience tests: garbage responses, timeouts, crashes, malformed streams
- Memory profiling: 2.3KB/finding, 15MB/1000 correlations
- Error message audit — 7 messages improved with actionable guidance
v3.7.0 shipped October 2026 — the GitHub Action requires Semgrep for code scans and fails the job when it cannot run, installs wheels only and uploads SARIF only for a finished scan, and a fatal Semgrep run is recorded as failed; no report-schema, SARIF, fingerprint or decision-policy changes, and every exit code keeps its meaning. v3.6.5 shipped October 2026 — Semgrep 1.182.1, MCP 1.29.0 and golang.org/x/mod 0.40.0 fix the last fixable HIGH advisories in the official image, Semgrep no longer contacts semgrep.dev, and self-hosted Linux CI runners need glibc 2.34 or later for Semgrep; no scanner, fingerprint, report-schema, decision-policy or exit-code changes. v3.6.4 shipped October 2026 — rebuilt on Go 1.27.3 and certifi 2026.10.23, so TLS no longer trusts the eight compromised emSign intermediate CAs and a hostile HTTP/2 scan target can no longer burn the scanner's CPU; no scanner, fingerprint, report-schema, decision-policy or exit-code changes. v3.6.3 shipped October 2026 — four bundled Semgrep rules that never matched now report, WARN by default under the confidence-gated --fail-on; the Flask auth advice says the decorator goes below @app.route(...); eleven checks have static catalog copy; no finding-identity change. v3.6.2 shipped October 2026 — diff-aware scans with a relative --code scan the changed files again, and a diff scope that cannot be represented safely falls back to a full scan. v3.6.1 shipped October 2026 — SARIF for a scan with no findings is valid, and the GitHub Action verifies the release signature before it runs the binary. v3.6.0 shipped October 2026 — baselines, .fendix-ignore rules and SARIF act on each security occurrence, so a baselined or ignored test fixture can no longer hide a new production credential grouped with it; baseline format v2, one SARIF result per occurrence, and fendix jira and fendix verify track every occurrence. v3.5.1 shipped October 2026 — fendix init writes CI that installs a pinned, signature-verified Fendix, brew upgrade reaches installs older Homebrew recorded as version 64, and the installer can require a signature or a pinned SHA-256; no scanner, fingerprint, report-schema, decision-policy or exit-code changes. v3.5.0 shipped October 2026 — --fail-on refuses an invalid threshold instead of silently scanning with none, fendix verify no longer reads missing input as a fix, and images publish to Docker Hub; no fingerprint, report-schema or decision-policy changes. v3.4.1 shipped September 2026 — the engine images now ship Go 1.27, raising govulncheck's module ceiling from 1.25; no scanner, fingerprint or exit-code changes, and the Go module floor stays 1.25. v3.4.0 shipped September 2026 — a scan can no longer look complete when it wasn't: every analyzer records whether it ran and why not, the report carries a coverage block that names the gaps, a URL scan with zero endpoints writes its report instead of vanishing, and two opt-in flags turn a coverage gap into a failing build. v3.3.0 shipped September 2026 — an upgrade no longer splits a finding you were already tracking into a closed one and a new one, and the list of checks a scan ran is built from what completed rather than what was configured. v3.2.0 — every blocking decision explains itself. A BLOCK now carries the policy it was made under and the evidence class that justified it, all the way through Fendix's own storage into the SARIF you export, so a failed pipeline is answerable from the report alone. Findings held back say why, confidence scores come with the rules that produced them, and a build blocked only because confidence enforcement was switched off is labelled as such. v3.1.0 stopped findings claiming more than they proved — wildcard CORS with credentials, rate-limit prioritisation, response-aware header grading, path-traversal wording, test-fixture credentials and dependency applicability all became more precise. v3.0 gave findings a stable identity based on which rule fired, in which file, in which function, about which operation. Re-save your baselines once after upgrading from before v3.0, and rewrite any .fendix-ignore rule that pins a fingerprint: value — rules using the supported id, endpoint or category selectors are unaffected by the fingerprint change, although positional SEC-NNN ids are suitable only for short-lived triage.