About vulnerability-core
Purpose
vulnerability-core is a minimal LinkML schema that defines the
shared, abstract foundation for representing software and hardware security
vulnerabilities across the lmodel family of vulnerability schemas. It is not a
standalone application model; it is the common base that source-specific
schemas import and specialize:
| Sibling schema | Source maintainer | Relationship to core |
|---|---|---|
| CVE | MITRE / CNAs | extends core |
| NIST NVD | NIST | imports core (NVDEntry is_a Vulnerability) |
| CISA KEV Catalog | CISA | imports core (KevEntry is_a Vulnerability) |
| CWE | MITRE | conceptually aligned (does not import core) |
The design goal is to factor out the concepts every vulnerability source shares — a CVE identifier, descriptions, affected products, weakness classifications, references, impact/severity, and lifecycle status — into one reusable vocabulary so the downstream schemas stay consistent and interoperable instead of re-inventing these types independently.
Design approach
The schema is a model-driven artifact. The hand-edited LinkML YAML at
src/vulnerability_core/schema/vulnerability_core.yaml is the single source of truth; every other representation under project/ (Python dataclasses and Pydantic, JSON Schema, JSON-LD, OWL, SHACL/ShEx, SQL DDL, GraphQL, Protobuf, TypeScript, Excel) is generated by gen-project and must never be hand-edited.
Abstract base + specialization
Vulnerability is declared abstract: true. It carries the slots common to
every source and is meant to be subclassed (via is_a / import) by the concrete
entries in the sibling schemas:
Vulnerability (abstract) ← this schema
├── cve_id (CveId, identifier, recommended)
├── title
├── description (recommended)
├── published_date / last_modified_date
├── products → Product (inlined list)
├── weaknesses → Weakness (inlined list)
├── references → Reference (inlined list)
├── impact → Impact
└── status (VulnerabilityStatus)
NVDEntry is_a Vulnerability (nist-nvd schema)
KevEntry is_a Vulnerability (kev-catalog schema)
The supporting value classes — Product, Reference, Weakness, Impact,
Configuration — are deliberately minimal pointers. For example
core:Weakness holds just cwe_id + name + description; the full canonical
weakness record lives in the CWE schema. Concrete schemas enrich these: NVD's
CVSSMetric is a far richer version of core's Impact, and NVD's
CPEConfiguration enriches core's Configuration.
Identity, types, and enums
CveIdis a custom string type constrained by^CVE-[0-9]{4}-[0-9]+$, so malformed identifiers fail validation.cve_idis theidentifierslot, mapped todcterms:identifier.IsoDateconstrains calendar dates toYYYY-MM-DD.VulnerabilityStatusenumerates lifecycle states (ACTIVE,REJECTED,DISPUTED,RESERVED,DEPRECATED).ImpactSeverityenumerates the CVSS qualitative ratings (NONE..CRITICAL, plusUNKNOWN).
Subsets
Two subsets partition the model for documentation and filtering: core
(cross-program vulnerability metadata) and metadata (identification and
reference fields such as cve_id and title).
Cross-schema harmonization via SSSOM
Because the value of an abstract base lies in how the concrete schemas relate to it, those relationships are recorded explicitly as SSSOM (Simple Standard for Sharing Ontological Mappings) TSV files under src/vulnerability_core/mappings/:
| Mapping file | Aligns core to | Primary relationship |
|---|---|---|
vulnerability_core_to_nist_nvd.sssom.tsv |
the lmodel NIST NVD schema | broadMatch (NVD narrows core) |
vulnerability_core_to_kev_catalog.sssom.tsv |
the lmodel KEV catalog schema | broadMatch (KEV narrows core) |
vulnerability_core_to_cwe.sssom.tsv |
the lmodel CWE schema | closeMatch / relatedMatch (no import) |
Each row pairs a subject_id (a core element) with an object_id (a sibling
element) using a SKOS predicate:
skos:broadMatch— core is the broader/abstract parent and the sibling is the narrower concrete form (used where the sibling actually inherits core via import, e.g.core:Vulnerability→nvd:NVDEntry,kev_catalog:KevEntry).skos:closeMatch— substantially the same concept (core:Reference→nvd:NVDReference;core:Weakness→cwe:Weakness).skos:relatedMatch— related but not a direct fit, often where one side flattens what the other structures (core:Product→ KEV'svendor_project/productfields).skos:exactMatch— identical, typically an inherited slot (core:cve_id→nvd:cve_id,kev_catalog:cve_id).
All mappings carry a semapv:LLMBasedMatching justification, making the
provenance and confidence of each alignment auditable and machine-readable.
The same intent is mirrored inside the schema itself with exact_mappings /
close_mappings / broad_mappings / related_mappings on classes and slots
(e.g. Vulnerability → nvd:NVDEntry and kev_catalog:KevEntry as broad
matches; Reference → cwe:ExternalReference as a close match).
Namespaces
Core's own terms resolve under https://w3id.org/lmodel/vulnerability-core/,
and CURIE prefixes for the sibling schemas (cwe:, nvd:, kev_catalog:)
point at their respective w3id identities, so a mapped term links straight to
its definition in the related schema.
Build pipeline
The project follows the linkml-project-copier layout. The quality gate after any schema edit is:
just lint # structural + convention checks
just gen-project # regenerate all downstream artifacts
just test # unit tests + example validation
Edits belong only in the schema YAML and the SSSOM mapping files. Everything
under project/ and src/vulnerability_core/datamodel/ is
generated. Documentation is built with MkDocs (Material theme); the rendered
site lives at https://lmodel.github.io/vulnerability-core.
Scope and roadmap
The current model (v1.0.0) deliberately keeps the value classes lean so concrete schemas can specialize them. Natural extensions include:
- Promoting
Impacttoward a full CVSS vector model (temporal / environmental metrics, CVSS 4.0) in the source-specific schemas. - Turning string discriminators such as
operator(Configuration) and the free-textvectorinto curated, ontology-backed enums. - Modeling CWE relationships (CAPEC attack-pattern links, weakness-abstraction hierarchy) as first-class references on the CWE side.