Inspiration

On 11 September 2026 the reporting duties of Article 14 of the EU Cyber Resilience Act started to apply. When a vulnerability in a product sold in the EU is exploited in the wild, its manufacturer has 24 hours to send an early warning, 72 hours to send a notification, and 14 days after the fix to send a final report, all through ENISA's Single Reporting Platform. Large vendors have a product security incident response team for this. A five person software company has the same deadlines and nobody whose job it is. The clock starts while the same people are still reading the advisory, writing the fix and fighting CI. We wanted a GitLab project that behaves like that missing team, and that writes down every fact the reports will need while the work happens.

What it does

Article 14 takes a CRA case from detection to the final report on GitLab:

  • Detects: every pipeline on main matches the product SBOM against OSV advisories and the CISA Known Exploited Vulnerabilities catalog.
  • Plans: a match opens a case issue with the three Article 14(2) clocks, labels, due date, a wiki fact sheet and an audit log.
  • Triages: a Duo flow proposes whether the case is reportable, citing only recorded facts.
  • Fixes: once the security lead confirms, a flow opens the fix merge request; when the upgrade breaks the build, another flow reads the job logs and repairs the code on the same branch.
  • Ships: image, CycloneDX SBOM, SAST, secret detection, dependency and container scanning, Terraform deployment to Cloud Run staging, monitor, smoke and Playwright tests, then production behind a manual job only the security lead can start, monitored with automatic rollback, released with notes written by a flow.
  • Reports: the three drafts are rendered from the fact sheet into a reports merge request, a flow proposes the narrative fields from the same facts, and every missing fact is shown as a GAP instead of a guess. Merging the merge request approves the drafts. The lead submits each report on the Single Reporting Platform personally and records it; the case closes with a recap.
  • Shows: a public dashboard with the running clocks, the timeline and the audit log of every case.

The demo product, Ledgerline, has a real vulnerability: CVE-2022-23540 in jsonwebtoken 8.5.1. It is not in the CISA KEV catalog, so the exploitation is simulated and the case runs as a clearly labelled DRILL. Nothing is ever sent to an authority.

How we built it

  • GitLab Duo Agent Platform: five custom flows in flow registry v1 YAML (triage, remediation, pipeline fix, release notes, CRA report), each enabled with its own service account and a mention trigger, plus a CRA advisor custom agent for Duo Chat. All of them are installed from the versioned files by a script that calls the AI Catalog GraphQL API through glab.
  • GitLab CI/CD: one pipeline definition split by stage, security templates, generic package registry for SBOMs, GitLab managed Terraform state, environments, releases, pipeline schedule, wiki pages as the versioned fact sheet and audit log.
  • Google Cloud: Cloud Run for staging and production, Artifact Registry, a Cloud Storage bucket for the public dashboard, Workload Identity Federation so CI never holds a key.
  • Node.js for the product, the case automation and the static dashboard generator; node:test, supertest and Playwright for tests. The dashboard is a port of our Claude Design mockups.

Lifecycle stages covered

All nine: Plan, Create, Verify, Package, Secure, Release, Configure, Monitor, Govern. The README maps each stage to the job, flow or agent that covers it with a link to the proof in this project.

Autonomy level

Supervised. Flows and pipelines do the work; a person approves four outcomes: the qualification (the confirming mention that also starts remediation), the merge of the green fix, the start of the production deployment, and the report drafts. Submissions to the authority stay manual by design.

Challenges

  • Flow triggers only fire on actions by a human user, so a flow cannot hand work to the next flow. We hand off from CI with a note posted on the owner's behalf, keep the token protected on main, and log every hand off.
  • The hackathon role cannot protect environments, change Pages visibility or set pipeline variables. Production became a manual job with an approver allowlist, the dashboard moved to a public bucket, and drills start from a manual job.
  • Cloud Run reserves URL paths ending in z, which swallowed /healthz.
  • Report drafting had to be useful without inventing anything. The renderer only uses the fact sheet and prints GAP for anything not recorded; the flow can only propose fields, attributed and marked for review.

What's next

  • Chain flows natively with the start_flow tool instead of CI hand offs.
  • Read vulnerability intelligence through an MCP server in the flows.
  • Support several products and group level cases, and the severe incident reports of Article 14(3).
  • Export drafts in the Single Reporting Platform format once ENISA publishes it.

Proof

Report drafts are drafts for review by a responsible person, not legal advice.

Built With

Share this project:

Updates

Submission history