-
-
cra-gate: EU Cyber Resilience Act-ready releases with GitLab Duo flows
-
How it works: deterministic CI produces the facts; two Duo flows add judgement and paperwork; the maintainer approves │
-
Flow 1 (Release Gate) on a release MR: reachability triage, SBOM hash, dossier commit and a PASS WITH JUSTIFICATION verdict
-
The scheduled cra:watch job fails on an exploited finding (labelled simulation), with a CI-computed fix plan
-
Flow 2 escalates the issue to "exploited" and computes the 24 h / 72 h / 14-day ENISA reporting deadlines
-
Flow 2's fix MR: exact version and git revision bump, plus a draft advisory and a draft ENISA early warning
-
The human gate: the maintainer merges the fix after Flow 1's PASS; the issue closes automatically
Inspiration
Since 11 September 2026 manufacturers of software sold in the EU must report actively exploited vulnerabilities to ENISA within 24 h (early warning), 72 h (notification) and 14 days after a fix (final report) — and from December 2027 must keep an SBOM and technical documentation for every release. Small teams treat this as paperwork after the code is done: scattered SBOMs, spreadsheets, and a scramble when an exploited CVE appears. That is exactly the "life after code".
What it does
cra-gate makes GitLab run the post-code lifecycle for CRA compliance:
- CI (deterministic): tests, container image, CycloneDX SBOM and an exploited-vulnerability check (CISA KEV / ENISA
EUVD / EPSS) with the open-source cra-scan; a scheduled
cra:watchre-scans the released lockfile. - Flow 1 — Release Gate: on a release MR, triages findings (including whether the vulnerable code is reachable), files issues, commits the Annex VII compliance dossier with the SBOM hash, and posts a PASS / PASS WITH JUSTIFICATION / BLOCK verdict.
- Flow 2 — Vulnerability Watch: when the watch fails, escalates the issue, computes the Art. 14 deadlines, opens a fix MR with the exact fixed version and git revision (computed by CI, never invented), a draft security advisory and a draft ENISA early warning.
- Supervised by design: the flows never merge. The maintainer — the legal "manufacturer" — starts the fix pipeline and approves the MR, so the human sign-off the law requires is the workflow's gate.
How we built it
GitLab Duo Agent Platform custom flows (YAML; agent components with GitLab API tools), triggered by pipeline events, plus
GitLab CI/CD, pipeline schedules with inputs, issues, MRs, labels and approvals. The agents' rules live in AGENTS.md.
The demo product is a small Swift (Hummingbird 2) service deployed to Cloud Run; the scanner is cra-scan (Apache-2.0, a
pinned PyPI dependency). Everything in the repository is MIT.
Challenges we ran into
- Agents cannot look up a git revision for a dependency bump → CI computes a fix plan and the agent only copies it.
- GitLab does not fire flow triggers for pipelines created by a flow's own service account → the maintainer's "Run pipeline" became the first human step of the gate (and prevents flows triggering each other in loops).
- Schedule inputs reached jobs masked, so the simulation switch is passed as a script argument instead.
- Demonstrating an exploited finding honestly → a clearly labelled simulation switch carried through every artifact.
- Our first Cloud Run deploy answered 503: a handler in the wrong place of the HTTP pipeline crashed the server, and our router-only tests could not see it. We fixed it and added a live-server regression test.
Accomplishments we're proud of
Two flows that cooperate through GitLab itself (issues, MRs, labels, notes) with a complete audit trail; a fix MR that
bumps both Package.swift and Package.resolved with the verified tag revision; covering all nine lifecycle stages
(plan, create, verify, package, secure, release, configure, monitor, govern).
What we learned
Keep facts deterministic and let the agents do judgement and drafting; write the rules for the agents as a plain file
(AGENTS.md); and test the unglamorous seams (triggers, tokens, bot-created pipelines), because that is where
automation breaks.
What's next
GitLab security-report output from cra-scan (so findings appear in the MR security widget), more ecosystems, a "CRA Advisor" chat agent that answers "are we ready to release X?", and ENISA Single Reporting Platform field mapping.
Built With
- cra-scan
- gitlab-ci/cd
- gitlab-duo-agent-platform-(custom-flows)
- gitlab-issues/mrs/schedules
- google-artifact-registry
- google-cloud-run
- hummingbird
- kaniko
- python
- swift
- swift-nio-extras
Log in or sign up for Devpost to join the conversation.