One record per security issue.
Every team reads the same one.
A CVE tells you what a vulnerability is. It does not tell you who exploits it, whether you can see it coming, or what your organization decided about it. CIR is an open YAML format that carries all of that in one record, split into layers you can share with exactly the right people.
Why CIR
Severity is not risk
A CVSS 9.8 behind validated egress filtering is not the same fire as a 6.5 on an internet-facing billing API. The score alone cannot tell them apart.
Context dies at every hop
SOC, vuln management, dev, CISO and business each rewrite the same issue in their own ticket, email or spreadsheet. Each copy loses something.
Internal issues have no home
A pentest finding, a misconfiguration, an in-house bug: no CVE, no common format. CIR describes them with the exact same structure as public ones.
The CVE says what it is. CIR says what it means for you.
Four layers, four audiences
- Layer 1 core What the issue is: identifiers (CVE, GHSA), affected products in the OSV model, CWE, CVSS, available fixes. CLEAR
- Layer 2 threat_intel Who exploits it, how and since when: exploit maturity, KEV and EPSS snapshots, actors, ATT&CK, IOCs. Everything dated and sourced. CLEAR
- Layer 3 posture How one entity stands against it, in enums only: reachability, controls, detection, blast radius. No names, no numbers, no free text. AMBER
- Layer 4 context What it means for one organization: assets, business and regulatory impact, decision, owner, SLA, who was told and when. RED
The posture layer is the bridge. A group or sector CERT can aggregate it across many
entities (most of you mitigate through segmentation
) without ever learning which assets are affected. How sharing works.
An identifier that says who issued it
Format: CIR, year, issuer code, sequence number. Example: CIR-2026-0CERTFR-0001.
- Starts with
0 - Public record.
00is the root authority; other codes such as0CERTFRmust be listed in the authorities registry. - Anything else
- Internal record, e.g.
CIR-2026-LAB-0012. Managed freely by the organization, no registration needed. - Extending
- An internal record can point to a public one with
based_onand inherit itscoreandthreat_intel, adding only its ownpostureandcontext.
Scores are computed, never typed in
From the retained CVSS score.
Active in the wild or KEV, public exploit, or none.
Contained, controlled or open.
Highest asset criticality or CIA impact.
Method cir-risk/0.1: deterministic, additive, explainable in a meeting. Anything unknown counts as the
worst case, so an empty layer never makes an issue look safer, and teams have a reason to fill it.
A record, trimmed
# Internal issue: pentest finding, no CVE. posture and context are illustrative.
cir_version: "0.1"
meta:
id: CIR-2026-LAB-0012
title: "IDOR on invoice export endpoint in billing-api"
tlp: AMBER
core:
tlp: AMBER
summary: "Any authenticated user can export another customer's invoices."
weaknesses: [CWE-639]
severity:
- { type: cvss_v3.1, score: 6.5, source: issuer, vector: "CVSS:3.1/AV:N/..." }
posture:
tlp: AMBER
status: { state: affected }
exposure: { reachability: internet, prevalence: rare }
context:
tlp: RED
decision: { action: fix, decided_by: "CISO" }
remediation: { owner: "Billing team", sla: P2-30d, status: in_progress }
Built on what already exists
- Identifiers
- CVE, GHSA and OSV are referenced as-is. Affected versions follow the OSV range model, so records import and export cleanly.
- Severity & weakness
- CVSS 3.1 and 4.0 vectors, CWE. The stored score must match the vector.
- Threat signals
- CISA KEV, EPSS, MITRE ATT&CK, STIX and MISP bundles, Sigma, YARA and friends for public detections.
- Sharing & status
- TLP 2.0 on every layer. Posture status is VEX-aligned, so it exports as a VEX statement.