DEV Community

Italo Armenti
Italo Armenti

Posted on

Compile a dated security-fix record from GitHub history with fixdossier

Under the revised EU Product Liability Directive (Directive (EU) 2024/2853, applicable December 9, 2026), software is explicitly covered as a product, national courts can order disclosure of relevant technical evidence in a dispute (Art. 9), and presumptions of defectiveness can apply if that evidence is not produced (Art. 10). Alongside the EU Cyber Resilience Act (Regulation (EU) 2024/2847)—which requires manufacturers to publish a clear security support period and maintain documented vulnerability handling—engineering teams need a dated, verifiable record of when each vulnerability was fixed, which release shipped the patch, and when security support ends for each release.

For most repositories, that raw data already exists in GitHub—scattered across GitHub Releases, tags, published GitHub Security Advisories (GHSAs), merged Dependabot/Renovate pull requests, and commit history.

fixdossier is an open-source (MIT), zero-dependency GitHub Action that compiles a dated security-fix record (SECURITY-RECORD.md + security-record.json) and a per-release support policy (SUPPORT.md) directly from your repository history.


Quick Start: GitHub Actions Workflow

Drop .github/workflows/security-record.yml into your repository:

name: security-record
on:
  release:
    types: [published]
  schedule:
    - cron: '0 6 * * 1'
  workflow_dispatch:

permissions:
  contents: write        # needed for mode: commit (mode: artifact needs only contents: read)
  pull-requests: read
  id-token: write        # optional: only needed when pro_upload: 'true'

jobs:
  record:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: itulo/fixdossier@v0
        with:
          support_period_months: 24
          eol_date: '2030-12-31'
          contact: 'security@example.com'
          output_dir: '.'          # default: '.'
          mode: 'commit'           # 'artifact' (default) | 'commit' | 'none'
          # pro_upload: 'true'     # optional: upload signed snapshot via GitHub Actions OIDC
Enter fullscreen mode Exit fullscreen mode

Using the standard GITHUB_TOKEN, fixdossier queries the GitHub API and writes three files to output_dir (default .), which are either uploaded as a workflow build artifact (mode: 'artifact', default) or committed directly to your branch (mode: 'commit'):

  1. SECURITY-RECORD.md — A dated security-fix log mapped to releases, bot dependency updates, release timeline, and any API coverage or permission gaps.
  2. security-record.json — Machine-readable output (schema: fixdossier/v1) for downstream automation or review tooling.
  3. SUPPORT.md — A standalone security support policy table computed from support_period_months, eol_date, and contact.

What the generated files look like

Below is a real excerpt generated by running fixdossier against axios/axios (SECURITY-RECORD.md and SUPPORT.md):

# Security record — axios/axios

_Generated 2026-10-12T13:36:53.690Z by fixdossier from GitHub data (releases, tags, security advisories, merged Dependabot/Renovate PRs, commit messages). Automatically compiled; review before relying on it. Not legal advice._

## Summary

| Item | Count |
|---|---|
| Published GitHub security advisories | 51 |
| Commits that look like security fixes | 2 |
| Merged bot dependency updates (security-flagged) | 43 (9) |
| Releases | 125 |
| Fixes not yet in a release | 0 |

## Security fixes (newest first)

| Date | Type | IDs | Fix | Shipped in | Release date | How mapped |
|---|---|---|---|---|---|---|
| 2026-09-16 | advisory (high) | GHSA-m8m8-qj5v-23w3, CVE-2026-101905 | [Node HTTP adapter prototype-pollution gadget allows request socket hijack via inherited createConnection](https://github.com/axios/axios/security/advisories/GHSA-m8m8-qj5v-23w3) | v1.20.0 | 2026-08-24 | advisory patched_versions |
| 2026-09-16 | advisory (high) | GHSA-r4gj-5m52-g5wh, CVE-2026-101907 | [maxRedirects: 0 is not enforced by the fetch adapter, allowing redirect-based SSRF](https://github.com/axios/axios/security/advisories/GHSA-r4gj-5m52-g5wh) | v1.20.0 | 2026-08-24 | advisory patched_versions |
| 2026-06-22 | commit | — | [chore(deps): bump form-data floor to ^4.0.6 to patch CRLF injection (#11028)](https://github.com/axios/axios/commit/5d2af0485354580dce4b6b77890b84cadc0ead0e) | v1.19.0 | 2026-07-26 | date heuristic (first release on/after commit) |
| 2026-05-24 | commit | CVE-2026-42264, GHSA-72mg-mc2j-cwf6 | [fix: guard socketPath with own() to prevent prototype pollution SSRF (#10901)](https://github.com/axios/axios/commit/140a17944a6ff175611597c874e218ad6c2afd1c) | v1.17.0 | 2026-06-03 | date heuristic (first release on/after commit) |

## Gaps in this record

- pull requests: stopped after 2 pages (raise max_pages for full history)
- commits: stopped after 2 pages (raise max_pages for full history)
Enter fullscreen mode Exit fullscreen mode

And the corresponding SUPPORT.md excerpt:

# Support policy — axios/axios

Security updates are provided for each release for **24 months** from its release date, and in any case not after **2030-12-31** (end of life).

Report vulnerabilities to: security@example.com. See SECURITY-RECORD.md for the dated history of security fixes.

| Release | Released | Security support until | Status |
|---|---|---|---|
| v0.34.0 | 2026-09-13 | 2028-09-13 | supported |
| v1.20.0 | 2026-08-24 | 2028-08-24 | supported |
| v1.19.0 | 2026-07-26 | 2028-07-26 | supported |
| v1.7.9  | 2024-12-04 | 2026-12-04 | supported |
| v1.7.2  | 2024-05-21 | 2026-05-21 | ended |
Enter fullscreen mode Exit fullscreen mode

How Release Mapping Works (and Why Explicit Heuristics Matter)

Mapping a security fix to the release that shipped it is harder than running git log --grep=CVE. Backports, maintenance branches, squash merges, and silent patches routinely trip up naive scripts.

Instead of pretending every row is 100% certain, fixdossier records the exact How mapped method on every row:

  1. advisory patched_versions (Highest confidence) — Matched directly from a published repository GitHub Security Advisory (GHSA-...) patched version string to its corresponding release tag (1.20.0 ↔ v1.20.0).
  2. tag commit match (High confidence) — The commit or PR merge SHA matches a release tag's commit SHA directly.
  3. date heuristic (first release on/after commit) (Requires human review) — Matched to the earliest stable release published on or after the fix timestamp. On repositories that backport fixes to older major branches, a date heuristic can point to the wrong branch's release.

If an API endpoint returns 401/403/404 or hits pagination limits (max_pages), fixdossier does not fail your build by default (unless fail_on_gaps: 'true'); instead, it logs the missing coverage explicitly under Gaps in this record.

Full unedited sample outputs from axios/axios, fastify/fastify, and vitejs/vite are available in examples/ and at fixdossier.dev.


Hosted Snapshots & Signed Evidence Packs

Need immutable hosted snapshots, a human review queue for heuristic matches, and signed PDF/ZIP evidence packs? fixdossier Pro connects directly to the Action via GitHub OIDC (pro_upload: 'true') — try the read-only interactive demo (Founding Licence: €69 one-time for 1 GitHub org, up to 3 repos and 5 reviewers, for as long as the service runs; 14-day EU refund policy).

Disclaimer: fixdossier is an engineering tool for evidence collection and review support, not legal advice and not a compliance certificate.

Feedback, issues, and PRs are welcome at github.com/itulo/fixdossier.

Top comments (0)