KGCS Documentation

Extending KGCS: Adding New Standards

Purpose: Guide for adding new security standards to KGCS.


When to Add to Core vs. Extension

Add to Core If

Examples: CPE, CVE, CWE, CAPEC, ATT&CK, D3FEND, CAR, SHIELD, ENGAGE

Add to Extension If

Examples: Incident, Risk, ThreatActor, RiskAssessment


Adding a Core Standard

Step 1: Define the Ontology

Create standards/<standard>/<standard>-ontology-v1.0.owl:

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:std="http://www.motherhacker.me/kgcs/ontology/<standard>#">

    <!-- Import core namespace -->
    <owl:imports rdf:resource="http://www.motherhacker.me/kgcs/ontology/core#"/>

    <!-- Define classes -->
    <owl:Class rdf:about="http://www.motherhacker.me/kgcs/ontology/<standard>#YourEntity">
        <rdfs:label>Your Entity</rdfs:label>
        <rdfs:comment>Definition and purpose</rdfs:comment>
    </owl:Class>

    <!-- Define properties -->
    <owl:DatatypeProperty rdf:about="http://www.motherhacker.me/kgcs/ontology/<standard>#yourProperty">
        <rdfs:domain rdf:resource="http://www.motherhacker.me/kgcs/ontology/<standard>#YourEntity"/>
        <rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
    </owl:DatatypeProperty>

    <!-- Define relationships -->
    <owl:ObjectProperty rdf:about="http://www.motherhacker.me/kgcs/ontology/<standard>#relatesTo">
        <rdfs:domain rdf:resource="http://www.motherhacker.me/kgcs/ontology/<standard>#YourEntity"/>
        <rdfs:range rdf:resource="http://www.motherhacker.me/kgcs/ontology/<standard>#OtherEntity"/>
    </owl:ObjectProperty>

</rdf:RDF>

Step 2: Write Human-Readable Spec

Create docs/02-ontology/<standard>-ontology-v1.0.md:

# [Standard] Ontology v1.0

## Overview
- **Source:** [Official spec URL]
- **Version:** v1.0 (frozen in KGCS)
- **Last Updated:** [Date]

## Core Entities
- **Class:** [Entity] ([Definition])
  - **Properties:** [property1], [property2], ...
  - **Example:** [ID: description]

## Relationships
- **Class A** --[edge]--> **Class B**
  - **Semantics:** [What this relationship means]

## Examples
[Real-world instances]

Step 3: Create SHACL Shapes

Create shapes/<standard>-shapes-v1.0.ttl:

@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix std: <http://www.motherhacker.me/kgcs/ontology/<standard>#>.

# Shape for YourEntity
std:YourEntityShape
    a sh:NodeShape;
    sh:targetClass std:YourEntity;
    sh:property [
        sh:path std:yourProperty;
        sh:minCount 1;
        sh:maxCount 1;
        sh:datatype xsd:string;
    ].

Step 4: Create Test Samples

Create positive and negative examples:

Step 5: Create ETL Transformer

Create src/etl/etl_<standard>.py:

from rdflib import Graph, Namespace, URIRef, Literal

class XyztoRDFTransformer:
    def __init__(self):
        self.graph = Graph()
        self.ns = Namespace("http://www.motherhacker.me/kgcs/ontology/<standard>#")

    def transform(self, json_data: dict) -> Graph:
        """
        Transform [Standard] JSON to RDF.

        Input: JSON from official source (API/download)
        Output: RDF Graph conforming to [standard]-shapes.ttl
        """
        for item in json_data.get("items", []):
            self._add_entity(item)
        return self.graph

    def _add_entity(self, item: dict):
        """Add an entity and its properties to graph."""
        entity_id = item.get("id")
        subj = self.ns[entity_id]

        # Type
        self.graph.add((subj, RDF.type, self.ns.YourEntity))

        # Properties
        self.graph.add((subj, self.ns.yourProperty, Literal(item.get("name"))))

        # Relationships
        for related_id in item.get("related", []):
            self.graph.add((subj, self.ns.relatesTo, self.ns[related_id]))

def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", "-i", required=True)
    parser.add_argument("--output", "-o", required=True)
    parser.add_argument("--validate", action="store_true")
    args = parser.parse_args()

    # Load JSON
    import json
    with open(args.input, 'r') as f:
        data = json.load(f)

    # Transform
    transformer = XyztoRDFTransformer()
    graph = transformer.transform(data)

    # Validate
    if args.validate:
        from src.core.validation import run_validator, load_graph
        shapes = load_graph("shapes/<standard>-shapes-v1.0.ttl")
        conforms, _, _ = run_validator(args.output, shapes, "artifacts")
        print("✓ PASS" if conforms else "✗ FAIL")

    # Save
    graph.serialize(destination=args.output, format="turtle")
    print(f"Saved {args.output}")

if __name__ == "__main__":
    main()

Step 6: Create Unit Tests

Create tests/test_<standard>_integration.py:

import json
import pytest
from src.etl.etl_<standard> import XyztoRDFTransformer
from src.core.validation import run_validator, load_graph

def test_<standard>_etl():
    """Test [Standard] ETL transformer."""
    # Load sample
    with open("data/<standard>/samples/sample_<standard>.json", "r") as f:
        data = json.load(f)

    # Transform
    transformer = XyztoRDFTransformer()
    graph = transformer.transform(data)

    # Assertions
    assert len(graph) > 0
    assert graph.query("SELECT ?s WHERE { ?s a ?YourEntity }")

Step 7: Update CI/CD

Add to .github/workflows/shacl-validation.yml:

- name: Validate [Standard]
  run: |
    python scripts/validate_shacl_stream.py \
      --data data/<standard>/samples/sample_<standard>.json \
    --shapes shapes/<standard>-shapes-v1.0.ttl

Step 8: Update Documentation

  1. Add to GLOSSARY.md — Standard definition + classes + relationships
  2. Add to architecture/architecture.md — Which phase, dependencies
  3. Update security/governance.md — Versioning policy, rollback procedure

Adding an Extension

Step 1: Define the Extension Ontology

Create extensions/<extension>-extension-v1.0.owl:

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:owl="http://www.w3.org/2002/07/owl#"
         xmlns:asset="http://www.motherhacker.me/kgcs/ontology/<extension>#"
         xmlns:kgcs="http://www.motherhacker.me/kgcs/ontology/core#">

    <!-- Import core ONLY (one-way) -->
    <owl:imports rdf:resource="http://www.motherhacker.me/kgcs/ontology/core#"/>

    <!-- Define extension classes -->
    <owl:Class rdf:about="http://www.motherhacker.me/kgcs/ontology/<extension>#YourContextualEntity">
        <rdfs:label>Contextual Entity</rdfs:label>
        <rdfs:comment>References core, adds context/subjectivity</rdfs:comment>
    </owl:Class>

    <!-- Reference core classes (don't redefine) -->
    <owl:ObjectProperty rdf:about="http://www.motherhacker.me/kgcs/ontology/<extension>#assesses">
        <rdfs:domain rdf:resource="http://www.motherhacker.me/kgcs/ontology/<extension>#YourContextualEntity"/>
        <rdfs:range rdf:resource="http://www.motherhacker.me/kgcs/ontology/core#Vulnerability"/>
    </owl:ObjectProperty>

</rdf:RDF>

Step 2: Create SHACL Shapes

shapes/<extension>-extension-shapes-v1.0.ttl

Step 3: Create Extension Spec

docs/02-ontology/<extension>-extension-ontology-v1.0.md

Step 4: Implement Python Module

src/extensions/<extension>.py — Load extension data independently

Step 5: Never Modify Core


Versioning Policy

Core Standards

CVSS Special Case

Extensions


Checklist for Adding a Standard


References