Skip to content

STIX schema reference

ZettelForge recognizes STIX-aligned entity types during extraction, stores STIX metadata fields on every note, and maintains a knowledge graph of relationships between entities. This page describes all three.

TypeDB STIX 2.1 ontology

The full STIX 2.1 TypeDB ontology — including TypeQL entity hierarchies, relation types, and inference functions — is available in ThreatRecall.ai, the hosted SaaS. The OSS package stores entity references in SQLite and an in-memory graph; the data structures on this page cover that path.


Entity types

ZettelForge extracts entities from text when you call remember(). Two extraction paths run in sequence:

  • Regex fast-path — deterministic, no LLM required. Covers CTI and IOC types.
  • LLM NER — conversational types. Requires a configured LLM provider.

CTI entity types (regex)

Entity type Example match Pattern
cve CVE-2024-1234 CVE-\d{4}-\d{4,}
intrusion_set APT28, UNC4990, TA505, FIN7 (apt\|unc\|ta\|fin\|temp)\s*-?\s*\d+
actor Lazarus, Sandworm, Volt Typhoon hardcoded known names
tool Cobalt Strike, Mimikatz, BloodHound hardcoded known names
campaign Operation Aurora operation\s+\w+
attack_pattern T1059, T1059.001 T\d{4}(?:\.\d{3})?

IOC entity types / STIX Cyber Observables (regex)

Entity type Description
ipv4 IPv4 address
domain Registered domain name
url HTTP/HTTPS URL
md5 32-character hex hash
sha1 40-character hex hash
sha256 64-character hex hash
email Email address

Conversational entity types (LLM NER)

Requires a configured LLM provider. Falls back to empty lists when no provider is available.

Entity type Description
person Named person (non-threat-actor context)
location Place name
organization Named organization
event Named event
activity Described activity
temporal Time expression

Entity type aliases in recall methods

recall_actor() searches across three entity types in one call: actor, threat_actor, and intrusion_set. All three map to the same lookup path.

recall_entity() accepts any entity type string directly. Pass "cve", "tool", "campaign", or any other recognized type.


Note metadata: STIX fields

Every MemoryNote carries these STIX-adjacent fields on its metadata object.

stix_confidence

Type: int
Default: -1 (unset)
Range: 0 to 100
Standard: STIX 2.1 confidence scale

Set automatically during OpenCTI sync when the source platform provides a confidence value. -1 means no STIX confidence has been assigned.

tier

Type: str
Default: "B"
Values: "A" | "B" | "C"

Epistemic tier:

Tier Meaning
A Authoritative — from a primary, verified source
B Operational — derived, processed, or synthesized
C Support — background, context, or low-confidence

tlp

Type: str
Default: "" (unclassified)
Values: "WHITE" | "GREEN" | "AMBER" | "RED" | ""

Traffic Light Protocol marking. Notes with AMBER or RED markings are excluded from snapshot exports unless an audited TLP override is provided.

confidence

Type: float
Default: 1.0
Range: 0.0 to 1.0

Internal confidence score. Decays when a note is evolved: each evolution caps confidence at 0.95. Distinct from stix_confidence.

vuln (VulnerabilityMeta)

Structured CVE scoring fields. Populated during OpenCTI sync, not during text extraction.

Field Type Description
cvss_v3_score float \| None CVSS v3 base score (0.0–10.0)
cvss_v3_vector str \| None CVSS v3 vector string, e.g. CVSS:3.1/AV:N/AC:L/...
epss_score float \| None EPSS exploitation probability (0.0–1.0, daily)
epss_percentile float \| None EPSS percentile relative to all scored CVEs (0.0–1.0)
cisa_kev bool True if the CVE is in the CISA Known Exploited Vulnerabilities catalog

vuln is None for non-CVE notes. For CVE notes before any OpenCTI sync, it is also None.


Knowledge graph relationship types

When you call remember(), ZettelForge heuristically creates edges in the knowledge graph when STIX-relevant entities co-occur in the same note. You can also write edges directly with ingest_relationship().

Edge types

Relationship From entity type To entity type Created by
MENTIONED_IN any note remember()
USES_TOOL actor, campaign tool remember() (heuristic)
EXPLOITS_CVE actor, tool cve remember() (heuristic)
TARGETS_ASSET actor, tool asset remember() (heuristic)
CONDUCTS_CAMPAIGN actor campaign remember() (heuristic)
SUPERSEDES note note mark_note_superseded()
TEMPORAL_BEFORE note note temporal ordering
TEMPORAL_AFTER note note temporal ordering

Heuristic edges are created when two entity types appear in the same note. They carry edge_type: "heuristic". Causal edges written via ingest_relationship() or provenance chains carry edge_type: "causal".

ingest_relationship()

Write a relationship edge directly into the knowledge graph without creating a memory note. Useful for sync clients that carry relationship data from external platforms.

mm.ingest_relationship(
    from_type="actor",
    from_value="apt28",
    to_type="tool",
    to_value="mimikatz",
    relationship="USES_TOOL",
    properties={"confidence": 0.9},
)

The call is idempotent: repeated writes with the same (from_type, from_value, to_type, to_value, relationship) tuple update the edge properties rather than creating duplicates.