Skip to content

Releases: Metbcy/securescan

v0.11.12

Choose a tag to compare

@github-actions github-actions released this 03 May 11:15

[0.11.12] - 2026-05-03

Patch: drop the cross-target restriction left behind by the v0.11.8
/compare/diff consolidation.

Fixed

  • Diff page silently sabotaged cross-target pairs and pointed users
    at a deleted page.
    Three artifacts of when /compare was a
    separate route:

    1. validateAndRun rejected pairs whose target_path differed
      with the message "Use Compare for cross-target diffs" — but
      Compare doesn't exist after v0.11.8 (it 308-redirects to
      /diff).
    2. handleBaseChange silently auto-cleared the head selection
      whenever the new base came from a different repo, with no UI
      hint that anything changed.
    3. headChoices filtered the head dropdown down to same-target
      scans only, so a "fork vs upstream" or "service-A vs service-B"
      diff couldn't even be selected.

    All three blocked legitimate use cases that the backend's
    /api/v1/scans/compare endpoint already supports. Removed the
    cross-target check entirely; b === h (same scan twice) remains
    the only real input error.

    Verified live: with a bomdrift scan as base, the head dropdown now
    shows scans from quantsense, securescan, and securescan-ss14 alongside
    the other bomdrift scans — pre-fix it would have shown only
    same-target options.


Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.12' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.12-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.12' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.12

v0.11.11

Choose a tag to compare

@github-actions github-actions released this 03 May 11:05

[0.11.11] - 2026-05-03

Patch: SARIF Download button uses an absolute URL.

Fixed

  • Dashboard "Download SARIF" button hit the in-app 404 page. The
    href was a relative path /api/v1/scans/<id>/report?format=sarif,
    which the browser resolves against the page origin (localhost:3000).
    Next.js's app router has no /api/v1/... route and falls through
    to the v0.11.6 custom not-found.tsx, so the user got
    "the URL you visited doesn't match any dashboard route" instead of
    the SARIF download. Next.js does NOT proxy /api/* to the FastAPI
    backend.

    Fix: new getScanReportUrl(scanId, format) helper in lib/api.ts
    that builds the absolute backend URL (http://localhost:8000/api/v1/...
    or whatever NEXT_PUBLIC_API_URL resolves to). The scan-detail
    page now calls it instead of templating a relative path. Pairs with
    the v0.11.10 backend fix where the endpoint started actually returning
    SARIF; without the absolute URL the user couldn't reach it.


Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.11' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.11-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.11' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.11

v0.11.10

Choose a tag to compare

@github-actions github-actions released this 03 May 08:15

[0.11.10] - 2026-05-03

Patch: SARIF download endpoint actually returns SARIF.

Fixed

  • GET /api/v1/scans/{id}/report?format=sarif silently fell through
    to the HTML branch because the handler only checked for format == "pdf"
    and returned HTML for everything else. The dashboard's "Download SARIF"
    button (in the scan-detail page header) has been emitting a 37 KB HTML
    page since launch — every download was a broken file that GitHub Code
    Scanning's upload action would reject.

    Wired the existing securescan.exporters.findings_to_sarif()
    generator (already used by the CLI's --output sarif path: deterministic
    ordering, partialFingerprints under securescan/v1 namespace,
    duplicate-fingerprint dedup, suppressed-finding filtering) into the
    endpoint. Returns application/sarif+json with a proper attachment
    Content-Disposition header. Tightened the format Query param with
    a regex pattern so unknown formats now 422 instead of silently
    defaulting to HTML — protects future callers from the same surprise.

Tests

  • 929 → 934 (+5): SARIF round-trip (status, content-type, attachment
    header, schema URL, results count); HTML default still works;
    unknown format rejected; 404 for missing scan; 400 for non-completed
    scan.

Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.10' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.10-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.10' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.10

v0.11.6

Choose a tag to compare

@github-actions github-actions released this 01 May 21:07

[0.11.6] - 2026-05-01

Frontend audit pass. Installed the
vercel-labs/next-skills
next-best-practices skill and applied it across the dashboard.

Added

  • app/error.tsx — app-level error boundary with friendly UI +
    retry button. Catches uncaught render/effect errors anywhere below
    the page boundary instead of dropping the user on Next's default
    red-screen overlay (which is what we hit when the dev server got
    stuck on stale 16.2.1 yesterday).
  • app/global-error.tsx — fallback for crashes above the page
    boundary (i.e. inside the root layout itself). Includes its own
    <html>/<body> because the root layout isn't rendered when
    this component takes over.
  • app/not-found.tsx — custom 404 inside the dashboard shell.
    Replaces Next's default "404 — This page could not be found" with
    an in-style page that keeps the sidebar/topbar visible and offers a
    "Back to overview" link.
  • lib/use-relative-time.ts + components/relative-time.tsx
    — render-safe relative-time hook. Uses useSyncExternalStore for
    a single shared 30s ticker (so a list of 100 timestamps doesn't
    spawn 100 setIntervals) and returns the empty string on the SSR
    / pre-hydration render so the post-mount label swap is a single
    text-node update with no layout shift.
  • frontend/.agents/skills/next-best-practices/ — the skill
    files themselves are checked in so any agent working in this repo
    picks them up automatically. skills-lock.json records the
    source + content hash for reproducible installs.

Changed

  • notification-bell.tsx, finding-row.tsx,
    history-table.tsx, command-palette.tsx — removed local
    formatRelative / relativeTime helpers (each called
    Date.now() during render → hydration mismatch warnings whenever
    the rounding boundary crossed between SSR and hydrate). All four
    now use the shared <RelativeTime /> component, which defers
    the calculation to client-side after mount.

Fixed

  • Hydration mismatch warnings on every page that displayed relative
    timestamps (most pages — notifications, history, scan-detail,
    command palette).

Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.6' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.6-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.6' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.6

v0.11.5

Choose a tag to compare

@github-actions github-actions released this 01 May 20:37

[0.11.5] - 2026-05-01

Patch release fixing notification body truncation.

Fixed

  • scan.complete notifications now show the target path. The
    scan.complete lifecycle event was published without a target
    field (only scan.start had one), so the notification body
    builder produced "20274 findings on " with a trailing space and
    no path. Added target=scan.target_path to the publish call.
    Belt-and-braces: the notification builder now also drops the
    " on " suffix when no target is supplied, so any future
    publishing-site regressions degrade gracefully to "<N> findings"
    instead of producing a dangling string.

    Pre-existing notifications keep their old bodies (they're
    immutable history); newly-created notifications use the fixed
    format.


Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.5' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.5-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.5' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.5

v0.11.4

Choose a tag to compare

@github-actions github-actions released this 01 May 19:30

[0.11.4] - 2026-05-01

Self-audit hotpatch. Ran SecureScan against itself, triaged the
findings, fixed the real issues, annotated the confirmed false
positives. Production high-severity findings dropped 31 → 1
(97% reduction); remaining one is the DAST scanner's intentional
verify=False against test URLs.

Fixed

  • GitHub Actions shell injection in .github/workflows/securescan.yml.
    The reusable workflow's run: block previously interpolated
    ${{ inputs.scan_path }} and friends directly. A malicious caller
    could smuggle shell metacharacters. Moved all three inputs into a
    per-step env: block; bash now sees them as quoted env values.

  • Vulnerable npm deps: next 16.2.1 → 16.2.4 (GHSA-q4gf-8mx6-v5v3 /
    CVE-2026-23869), postcss 8.4.31/8.5.8 → 8.5.13 everywhere
    (GHSA-qx2v-qp2m-jg93 / CVE-2026-41305). The deeply-nested
    node_modules/next/node_modules/postcss was deduped via an npm
    overrides self-reference. npm audit: 0 vulnerabilities.

  • Frontend Dockerfile runs as the non-root node user (uid 1000)
    with a wget-based HEALTHCHECK. Defense in depth — RCE in the
    Next.js process no longer means root inside the container.

  • .github/workflows/securescan.yml now declares a top-level
    permissions: contents: read. Existing per-job permissions:
    blocks continue to opt back in to security-events: write where
    needed; the top-level default protects against future jobs added
    without explicit permissions.

  • Secrets scanner false-positive detection got smarter. Three
    new heuristics, applied to every line:

    • Truncation ellipsis (SECRET = "abc...32-chars...")
    • Shell command substitution (SECRET="$(openssl rand -hex 32)")
    • Self-describing short placeholders (API_KEY=zap-api-key-from-zap-ui)

    Closes 21 high-severity FPs in our own docs; same noise reduction
    for every downstream user. Notably does NOT blanket-skip .md files
    — real secrets do leak in committed README files.

  • reports.py — swapped autoescape=True for
    autoescape=jinja2.select_autoescape(["html", "xml"]). Functionally
    identical; satisfies semgrep's preferred shape.

  • database.py — annotated the 5 sqlalchemy-execute-raw-query +
    3 B608 findings on the DDL allowlist sites (already audited and
    protected by _safe_ident() since v0.10.3) with # nosemgrep /
    # nosec markers. Behavior unchanged; future audits stay clean.

Tests

  • 929 passing throughout (no test changes; behavior-preserving fix).
  • Verified end-to-end via Playwright re-scan of SecureScan against
    itself — production findings: 77 → 33 (high 31 → 1, medium 24 → 10).

Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.4' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.4-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.4' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.4

v0.11.3

Choose a tag to compare

@github-actions github-actions released this 01 May 08:00

[0.11.3] - 2026-05-01

Patch release fixing the real root cause of the dashboard hanging
during scans on large projects. The v0.11.2 frontend-only fix was
correct as far as it went, but did not address the underlying
event-loop block.

Fixed

  • Scanners no longer block the asyncio event loop with synchronous
    filesystem walks.
    Every scanner that did a sync os.walk() or
    Path.rglob() was running it directly inside its async scan()
    method, which on Python's asyncio means it monopolises the event
    loop until done. With 11 scanners running concurrently against a
    large project (e.g. a 4 GB Rust monorepo with 12 K files in
    target/), the loop was fully starved for the entire scan
    duration — /health timed out (dashboard "API Offline" badge),
    scanner.start SSE events couldn't be flushed (live progress
    panel showed nothing), and even simple GETs queued behind the
    walks. Reproduced via a Playwright-driven test against the live
    dashboard: /health was unreachable for 24+ s during a bomdrift
    scan; post-fix it answers in <2 ms throughout the run.

    Sync walks moved to asyncio.to_thread() in:

    • bandit.py: the "is there any Python code in this tree?" pre-check
    • secrets.py: the file enumeration AND the per-file read+regex
      batch (the heaviest path — touches every scannable file)
    • dockerfile.py: the rglob for Dockerfile patterns
    • gitleaks.py: the sensitive-file rglob sweep
    • npm_audit.py: the package.json discovery walk
    • safety.py: the requirements*.txt discovery walk
  • Live progress panel renders immediately on the scan-detail page.
    Inherited from v0.11.2 — page no longer awaits fetchFindings
    on initial mount of a running scan. SSE drives progress; the SSE
    terminal handler populates the findings table after scan.complete.

Tests

  • 929 still passing. No new tests added — the fix is verified
    end-to-end via Playwright reproduction of the original symptom
    (/health reachable throughout a multi-minute scan, dashboard
    topbar stays "Connected", per-scanner progress streams live).

Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.3' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.3-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.3' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.3

v0.11.2

Choose a tag to compare

@github-actions github-actions released this 01 May 07:44

[0.11.2] - 2026-04-30

Patch release fixing the dashboard's scan-detail page hanging on
projects that produce many findings.

Fixed

  • Scan-detail page no longer blocks initial render on
    fetchFindings.
    When a user navigated to /scan/[id] while
    the scan was still running, the page awaited the full findings list
    before rendering, even though the SSE stream is what drives the
    live progress panel. On a project producing tens of thousands of
    findings (e.g. a 4 GB Rust monorepo where bandit enumerates
    every file in target/), the GET could return >10 MB of JSON
    and serialize behind the orchestrator's concurrent finding INSERTs
    — making the dashboard appear to "hang" until the scan completed.

    The page now skips the initial findings fetch when status is
    running or pending. The SSE stream delivers per-scanner
    scanner.start / scanner.complete events as before, and the
    SSE terminal handler already calls load() after
    scan.complete to populate the findings table at the right
    moment. No backend change required; no scanner exclusions required.


Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.2' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.2-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.2' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.2

v0.11.1

Choose a tag to compare

@github-actions github-actions released this 01 May 07:33

[0.11.1] - 2026-04-30

Patch release fixing a false-positive "API Offline" indicator in the
dashboard during heavy scans.

Fixed

  • /ready no longer runs schema migrations on every probe. The
    endpoint was calling init_db() per request, which issues ~15
    DDL statements (CREATE TABLE / ALTER TABLE / CREATE INDEX). Under
    concurrent scan-write load (11 scanners writing findings in
    parallel), the ALTER TABLEs would block on SQLite's write lock past
    the 5s busy_timeout, returning 503 and making the dashboard's
    topbar status indicator flip from "Connected" to "Offline" mid-scan.
    /ready now uses a new db_ping() helper (single SELECT 1),
    unaffected by write contention. init_db() is also now idempotent
    fast-path: subsequent calls return immediately after the first
    successful schema setup.

Tests

  • 929 → 930 (+1): regression test asserting /ready does not invoke
    init_db.

Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.1' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.1-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.1' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.1

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 30 Apr 23:39

[0.11.0] - 2026-04-30

OSS adoption foundations release: a 60-second first-run path, a
pre-commit hook, PyPI publishing via OIDC, comparison docs against
DefectDojo / Trivy / Snyk, a CONTRIBUTING file, and a release-cadence
commitment. No breaking changes.

Added

  • securescan init wizard. Detects the project's stack
    (Python / Node / Rust / Go / Container / IaC + multi-language) and
    writes .securescan.yml, .github/workflows/securescan.yml, and
    .securescan/baseline.json in one command. Idempotent (refuses
    to overwrite existing files unless --force). Interactive prompts
    with --no-prompt for scripted setup. Generated config rounds-trips
    through the existing parse_config loader so output is guaranteed
    schema-valid.
  • pre-commit hook + --staged flag. New .pre-commit-hooks.yaml
    at the repo root; new pre-commit-securescan console script
    installed alongside securescan. The hook runs securescan scan --staged, which uses git diff --cached --name-only --diff-filter= ACMRT to limit the scan to staged changes (sub-3s on small
    projects). Empty stage exits 0. Outside a git repo: clear error.
    See docs/src/integrations/pre-commit.md for the
    .pre-commit-config.yaml snippet.
  • PyPI publishing via OIDC Trusted Publishers. The publish-pypi
    job in .github/workflows/release.yml no longer needs a
    PYPI_TOKEN secret. The first time a vX.Y.Z tag is pushed after
    the one-time pypi.org setup completes (see docs/PUBLISHING.md),
    PyPI accepts the upload via short-lived OIDC tokens issued by
    GitHub Actions. The job's environment: pypi + permissions: id-token: write are how PyPI verifies the claim. No token
    rotation, no secret management.
  • CONTRIBUTING.md at the repo root with dev-setup commands,
    test commands, code-style rules (ruff, mypy, conventional commits),
    PR process, security-disclosure address, code-of-conduct ref.
  • docs/src/reference/release-cadence.md committing to monthly
    minor releases (first Monday) + on-demand patches, with explicit
    deprecation policy (≥60 days notice, runtime warnings, CHANGELOG).
  • OpenAPI surface documented. New docs/src/api/openapi.md
    pointing at the auto-generated /api/v1/openapi.json endpoint
    (FastAPI ships this for free) plus interactive /docs (Swagger
    UI) and /redoc surfaces. With Postman / Insomnia / Backstage
    import recipes.
  • Comparison docs. Three new pages under docs/src/compare/:
    • vs-defectdojo.md — different categories; many teams use both.
    • vs-trivy.md — SecureScan wraps Trivy and adds 13 more scanners.
    • vs-snyk.md — OSS, self-hosted, deterministic vs. SaaS reachability.

Changed

  • README quick-start (60 seconds). First 30 lines are now
    pip install <wheel-url> + securescan init + securescan diff
    with copy-pasteable commands. Screenshots and dashboard tour
    preserved below the fold. Outdated "What's new in v0.6.0" callout
    removed.
  • Image / tag drift fixed across the docs. Every @v0.2.0,
    @v0.6.0, @v0.9.0, @v0.10.2 reference in user-facing docs
    bumped to either @v1 (mutable major, recommended) or @v0.10.3
    / @v0.11.0 (exact pin). New "Action versioning" section in
    README explains the contract.
  • release.yml's publish-pypi job migrated from twine + PYPI_TOKEN
    to pypa/gh-action-pypi-publish@release/v1 with OIDC Trusted
    Publishers. The associated if: PYPI_TOKEN configured gate is
    gone; the job runs on every tag.

Tests

  • 887 → 929 (+42): 27 new for securescan init, 15 new for the
    staged-scan / pre-commit path.

Backward compatibility

  • No CLI flag removals.
  • No REST API path removals.
  • No config schema changes.
  • Existing Metbcy/securescan@v1 Action consumers unaffected.

Out of scope (deferred — see GitHub issues)

  • VS Code extension (P2.4).
  • Hosted public demo on Fly.io / Railway (P3.4).
  • securescan up zero-config dashboard (P1.3) — frontend not in
    the wheel today.
  • GitLab CI / Bitbucket Pipelines PR-comment renderers (P2.1, P2.2).
  • Homebrew tap (P1.7).

Verifying signatures

Wheel + sdist (sigstore-python)

pip install sigstore
sigstore verify identity \
  --cert-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.0' \
  --cert-oidc-issuer https://token.actions.githubusercontent.com \
  securescan-0.11.0-py3-none-any.whl

Container image (cosign keyless)

cosign verify \
  --certificate-identity 'https://github.com/Metbcy/securescan/.github/workflows/release.yml@refs/tags/v0.11.0' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/metbcy/securescan:v0.11.0