Skip to content

Add Capability class and capability namespace to support modular, graph-based capability assertions (Tool/Module/Parser decomposition) #682

Description

@vulnmaster

Target release

Target: UCO 1.6.0

Attribution and status

This proposal is a joint effort between Vulnmaster (Cory Hall) and sbarnum (Sean Barnum). The decomposed Tool → Module → Parser → Capability model is informed by Sean Barnum's data model work. The proposal is ready for community review.

Background

UCO currently lacks a Capability class to formally describe what an entity — a tool, software module, person, organization, or threat actor — is able to do. The concept of capability is fundamental across multiple UCO use cases:

  • Forensic tool comparison: Which tools can parse which application data on which platforms? Labs and organizations like the NIST CFTT programme, the University College Dublin AutoDFBench project, and the SOLVE-IT framework (Chris Hargreaves) all need to model and compare forensic tool capabilities.
  • Cyber threat intelligence: What capabilities does a threat actor group possess (e.g., ability to exploit a specific vulnerability, ability to conduct lateral movement)?
  • Software assurance / SBOM: What can a piece of software do? A capability declaration enables attack surface analysis (e.g., "this software can parse PDF files → all PDF injection vectors are relevant").
  • Human resource management: What capabilities does a forensic examiner possess (certifications, skills, training)?

Without a dedicated Capability class, practitioners must either embed capability descriptions as unstructured strings or create ad-hoc extension classes like toolcap:ToolCapability that couple capability semantics to a specific domain. A general-purpose Capability class in UCO would enable modular, graph-based capability assertions that can be shared across organizations, compared, and queried using standard SPARQL patterns.

The existing uco-action:ActionPattern class (in uco.action) already provides the ideal mechanism for structured characterization of what a capability entails: an ActionPattern can specify the action type (e.g., "parse"), the target objects (e.g., a specific file type), and the expected results (e.g., EmailMessage instances). What is missing is a Capability class to serve as the anchor point linking entities to their abilities via uco-core:Relationship.

This proposal also introduces Module and Parser as subclasses of uco-observable:Software. These classes are needed to decompose forensic tool architectures into their component parts — tools contain modules, modules use parsers — before relating them to capabilities. This decomposition enables graph-based path-finding queries such as "which tool → module → parser chain can produce text messages from an iOS Snapchat database?"

Related proposals and references

Requirements

Requirement 1: Capability class

Define a new Capability class as a subclass of uco-core:UcoObject.

A capability is the ability of an entity to perform some action or produce some result. Capabilities are connected to their possessors (tools, modules, parsers, people, organizations) via uco-core:Relationship instances with kindOfRelationship="hasCapability".

Properties:

  • structuredCharacterization (object property → uco-action:ActionPattern, 0..1): A structured representation of what this capability entails, expressed as an ActionPattern specifying the action type, target objects, and expected results. When omitted, the capability is described only by its name and description properties inherited from UcoObject.
  • capabilityScope (datatype property → xsd:string, 0..*): A categorization of the capability domain (e.g., "forensic-parsing", "data-acquisition", "threat-operation", "software-assurance", "human-skill"). Enables filtering capabilities by domain without inspecting the ActionPattern structure.

Requirement 2: Module class

Define a new Module class as a subclass of uco-observable:Software.

A module is a discrete, potentially reusable component of a larger software system. In forensic tool architectures, a module represents a pluggable unit of functionality — for example, a parsing module for a specific application, a carving module for a specific file type, or a decryption module.

Properties:

  • analyticFocus (object property → uco-observable:ObservableObject, 0..*): The primary observable object(s) — typically an Application — that this module is designed to analyze or process. For example, a forensic parsing module focused on Snapchat iOS would have analyticFocus pointing to the Snapchat iOS Application instance.

Requirement 3: Parser class

Define a new Parser class as a subclass of uco-observable:Software.

A parser is a type of software that takes structured or semi-structured input data and extracts meaningful content from it. In forensic contexts, parsers are the components that read application databases, file formats, and data structures to produce observable artifacts (messages, contacts, files, etc.).

Note: Parser could alternatively be modeled as a subclass of Module. The committee should consider whether Parser rdfs:subClassOf Module is more appropriate than Parser rdfs:subClassOf Software. Both Module and Parser would remain subclasses of Software either way.

Risk / Benefit analysis

Benefits

  • Universal applicability: A single Capability class serves forensic tools, CTI, SBOM, and HR use cases — three or more orders of magnitude broader than a tool-specific class.
  • Graph-based queries: Capability assertions via Relationships enable SPARQL path traversal (Tool → Module → Parser → Capability → ActionPattern → result type), supporting use cases like SOLVE-IT's risk-rated path-finding.
  • Modular assertions: Different organizations can independently assert capabilities about the same tools/modules without modifying shared objects — just add new Relationship and Capability nodes to the graph.
  • Structured characterization: Leveraging the existing ActionPattern class enables machine-readable capability descriptions without inventing new vocabulary.
  • Registry potential: Well-known Capability instances (e.g., "Parse Snapchat messages", "Carve JPEG files") can be published as shared individuals for cross-organization consistency.

Risks

  • Complexity: The decomposed model (Tool → Module → Parser → Capability → ActionPattern) has more nodes than a monolithic ToolCapability. Mitigation: SDK helper functions can generate the full chain from simple inputs.
  • Dependency on ActionPattern: The structuredCharacterization property depends on uco-action:ActionPattern being stable. Mitigation: ActionPattern has been in UCO since early versions and is well-established.
  • Module/Parser placement: There is an open question about whether these belong in uco-observable (as Software subclasses) or in a new or existing namespace. The committee should weigh in.

Competencies demonstrated

Scenario

A DFIR lab manages three forensic tools: Autopsy (open-source), Cellebrite UFED (commercial), and an internal extraction framework called "Kestrel". Each tool has multiple modules. The lab needs to determine:

  1. Which tools can parse Snapchat messages from iOS devices
  2. Which modules and parsers are involved in that capability chain
  3. What benchmark results exist for those capabilities

Objects in the example graph

  • Tools: Autopsy, Cellebrite UFED
  • Modules: "Snapchat iOS Module" (used by Autopsy), "Snapchat Parser Module" (used by Cellebrite UFED)
  • Parsers: "main.db Parser" (Snapchat's SQLite database parser)
  • Capability: "Parse Snapchat messages from main.db"
  • ActionPattern: action="parse", object=File("main.db"), result=Message
  • Application: Snapchat iOS
  • OperatingSystem: iOS

Competency Question 1

Question: Which tools have a capability to parse Snapchat messages?

Expected result: Autopsy, Cellebrite UFED

Competency Question 2

Question: For each tool with Snapchat message parsing capability, what is the full chain from tool to module to capability to action pattern?

Expected result:

  • Autopsy →(mayUse)→ Snapchat iOS Module →(hasCapability)→ "Parse Snapchat messages" →(structuredCharacterization)→ ActionPattern(parse, main.db, Message)
  • Cellebrite UFED →(mayUse)→ Snapchat Parser Module →(hasCapability)→ "Parse Snapchat messages" →(structuredCharacterization)→ ActionPattern(parse, main.db, Message)

Competency Question 3

Question: Which modules focus on the Snapchat iOS application?

Expected result: Snapchat iOS Module, Snapchat Parser Module

Draft SPARQL

# CQ1: Which tools have a capability to parse Snapchat messages?
PREFIX uco-core: <https://ontology.unifiedcyberontology.org/uco/core/>
PREFIX uco-action: <https://ontology.unifiedcyberontology.org/uco/action/>
PREFIX uco-observable: <https://ontology.unifiedcyberontology.org/uco/observable/>
PREFIX proposed: <https://proposed.ontology.unifiedcyberontology.org/uco/capability/>

SELECT DISTINCT ?tool ?toolName ?capName
WHERE {
    # Tool -[mayUse]-> Module
    ?rel1 a uco-core:Relationship ;
          uco-core:kindOfRelationship "mayUse" ;
          uco-core:source ?tool ;
          uco-core:target ?module .

    # Module -[hasCapability]-> Capability
    ?rel2 a uco-core:Relationship ;
          uco-core:kindOfRelationship "hasCapability" ;
          uco-core:source ?module ;
          uco-core:target ?cap .

    ?cap a proposed:Capability ;
         proposed:structuredCharacterization ?pattern .

    ?pattern uco-action:result ?result .
    ?result a uco-observable:Message .

    ?tool uco-core:name ?toolName .
    ?cap uco-core:name ?capName .
}

Example instance data

The full example graph is embedded below; it has been validated with case_validate and tested against the competency question SPARQL queries.

{
  "@context": {
    "kb": "http://example.org/kb/",
    "proposed": "https://proposed.ontology.unifiedcyberontology.org/uco/capability/",
    "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
    "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/",
    "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
    "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/",
    "xsd": "http://www.w3.org/2001/XMLSchema#"
  },
  "@graph": [
    {
      "@id": "kb:tool-autopsy-aaaaaaaa-1111-4aaa-b111-111111111111",
      "@type": "uco-tool:Tool",
      "uco-core:name": "Autopsy",
      "uco-tool:version": "4.21.0"
    },
    {
      "@id": "kb:tool-ufed-bbbbbbbb-2222-4bbb-c222-222222222222",
      "@type": "uco-tool:Tool",
      "uco-core:name": "Cellebrite UFED",
      "uco-tool:version": "8.5.0"
    },
    {
      "@id": "kb:app-snapchat-ios-cccccccc-3333-4ccc-d333-333333333333",
      "@type": "uco-observable:Application",
      "uco-core:name": "Snapchat iOS"
    },
    {
      "@id": "kb:os-ios-dddddddd-4444-4ddd-e444-444444444444",
      "@type": ["uco-observable:OperatingSystem", "uco-observable:Software"],
      "uco-core:name": "iOS"
    },
    {
      "@id": "kb:module-snapchat-autopsy-eeeeeeee-5555-4eee-f555-555555555555",
      "@type": "proposed:Module",
      "uco-core:name": "Snapchat iOS Module",
      "uco-core:description": "Autopsy module for parsing Snapchat iOS application data",
      "proposed:analyticFocus": {"@id": "kb:app-snapchat-ios-cccccccc-3333-4ccc-d333-333333333333"}
    },
    {
      "@id": "kb:module-snapchat-ufed-ffffffff-6666-4fff-a666-666666666666",
      "@type": "proposed:Module",
      "uco-core:name": "Snapchat Parser Module",
      "uco-core:description": "Cellebrite UFED module for parsing Snapchat iOS data",
      "proposed:analyticFocus": {"@id": "kb:app-snapchat-ios-cccccccc-3333-4ccc-d333-333333333333"}
    },
    {
      "@id": "kb:parser-maindb-11111111-7777-4111-b777-777777777777",
      "@type": "proposed:Parser",
      "uco-core:name": "main.db Parser",
      "uco-core:description": "Parser for Snapchat's main.db SQLite database"
    },
    {
      "@id": "kb:file-maindb-22222222-8888-4222-c888-888888888888",
      "@type": "uco-observable:File",
      "uco-core:name": "main.db"
    },
    {
      "@id": "kb:action-parse-snapchat-33333333-9999-4333-d999-999999999999",
      "@type": "uco-action:ActionPattern",
      "uco-core:name": "parse",
      "uco-action:object": [{"@id": "kb:file-maindb-22222222-8888-4222-c888-888888888888"}],
      "uco-action:result": [{"@id": "kb:result-message-type-44444444-aaaa-4444-eaaa-aaaaaaaaaaaa"}]
    },
    {
      "@id": "kb:result-message-type-44444444-aaaa-4444-eaaa-aaaaaaaaaaaa",
      "@type": "uco-observable:Message",
      "uco-core:name": "Snapchat chat message"
    },
    {
      "@id": "kb:cap-parse-snapchat-55555555-bbbb-4555-fbbb-bbbbbbbbbbbb",
      "@type": "proposed:Capability",
      "uco-core:name": "Parse Snapchat messages from main.db",
      "uco-core:description": "The ability to parse Snapchat chat messages from the main.db SQLite database found on iOS devices",
      "proposed:structuredCharacterization": {"@id": "kb:action-parse-snapchat-33333333-9999-4333-d999-999999999999"},
      "proposed:capabilityScope": "forensic-parsing"
    },
    {
      "@id": "kb:rel-autopsy-module-66666666-cccc-4666-accc-cccccccccccc",
      "@type": "uco-core:Relationship",
      "uco-core:source": [{"@id": "kb:tool-autopsy-aaaaaaaa-1111-4aaa-b111-111111111111"}],
      "uco-core:target": {"@id": "kb:module-snapchat-autopsy-eeeeeeee-5555-4eee-f555-555555555555"},
      "uco-core:kindOfRelationship": "mayUse",
      "uco-core:isDirectional": true
    },
    {
      "@id": "kb:rel-ufed-module-77777777-dddd-4777-bddd-dddddddddddd",
      "@type": "uco-core:Relationship",
      "uco-core:source": [{"@id": "kb:tool-ufed-bbbbbbbb-2222-4bbb-c222-222222222222"}],
      "uco-core:target": {"@id": "kb:module-snapchat-ufed-ffffffff-6666-4fff-a666-666666666666"},
      "uco-core:kindOfRelationship": "mayUse",
      "uco-core:isDirectional": true
    },
    {
      "@id": "kb:rel-module-cap-88888888-eeee-4888-ceee-eeeeeeeeeeee",
      "@type": "uco-core:Relationship",
      "uco-core:source": [{"@id": "kb:module-snapchat-autopsy-eeeeeeee-5555-4eee-f555-555555555555"}],
      "uco-core:target": {"@id": "kb:cap-parse-snapchat-55555555-bbbb-4555-fbbb-bbbbbbbbbbbb"},
      "uco-core:kindOfRelationship": "hasCapability",
      "uco-core:isDirectional": true
    },
    {
      "@id": "kb:rel-module-cap2-99999999-ffff-4999-dfff-ffffffffffff",
      "@type": "uco-core:Relationship",
      "uco-core:source": [{"@id": "kb:module-snapchat-ufed-ffffffff-6666-4fff-a666-666666666666"}],
      "uco-core:target": {"@id": "kb:cap-parse-snapchat-55555555-bbbb-4555-fbbb-bbbbbbbbbbbb"},
      "uco-core:kindOfRelationship": "hasCapability",
      "uco-core:isDirectional": true
    },
    {
      "@id": "kb:rel-app-runs-on-aaaaaa00-1111-4aaa-b111-000000000000",
      "@type": "uco-core:Relationship",
      "uco-core:source": [{"@id": "kb:app-snapchat-ios-cccccccc-3333-4ccc-d333-333333333333"}],
      "uco-core:target": {"@id": "kb:os-ios-dddddddd-4444-4ddd-e444-444444444444"},
      "uco-core:kindOfRelationship": "runs-on",
      "uco-core:isDirectional": true
    }
  ]
}

I am fine with my examples being transcribed and credited.

Solution suggestion

  1. Define new class uco-capability:Capability as a subclass of uco-core:UcoObject in a new uco/capability namespace
  2. Define object property uco-capability:structuredCharacterization with domain Capability and range uco-action:ActionPattern
  3. Define datatype property uco-capability:capabilityScope with domain Capability and range xsd:string
  4. Add SHACL shape for Capability with property constraints
  5. Define new class Module as a subclass of uco-observable:Software (placement in uco-observable or a new namespace TBD by committee)
  6. Define object property analyticFocus with domain Module and range uco-observable:ObservableObject
  7. Add SHACL shape for Module with property constraints
  8. Define new class Parser as a subclass of uco-observable:Software (committee to decide if also subclass of Module)
  9. Add SHACL shape for Parser
  10. Add unit test(s) demonstrating valid and invalid usage
  11. Define recommended kindOfRelationship vocabulary terms for use with uco-core:Relationship: "hasCapability", "mayUse", "uses", "runs-on", "variation-of", "isVersionOf"

Pre-submission testing

Run make test-proposal PROPOSAL=capability-namespace to execute all tests.

SPARQL query testing

Query Tested Expected results match Notes
CQ 1 — Tools with Snapchat parsing capability Yes Yes 2 results: Autopsy, Cellebrite UFED
CQ 2 — Full tool→module→capability chain Yes Yes 2 chains, both reaching the shared Capability and ActionPattern
CQ 3 — Modules by analytic focus Yes Yes 2 results: Snapchat iOS Module, Snapchat Parser Module
$ make test-proposal PROPOSAL=capability-namespace
=== Validating proposal graph: change_proposals/capability-namespace.jsonld ===
Validation Report
Conforms: True
=== Testing SPARQL queries for proposal: capability-namespace ===
Loaded 60 triples from change_proposals/capability-namespace.jsonld
  Query 1: 2 result(s) — OK
  Query 2: 2 result(s) — OK
  Query 3: 2 result(s) — OK

SPARQL test summary: 3 passed, 0 failed

Graph validation

$ case_validate --built-version case-1.4.0 \
    --ontology-graph change_proposals/capability-namespace.ttl \
    --ontology-graph change_proposals/capability-namespace-shapes.ttl \
    --inference rdfs --allow-info \
    change_proposals/capability-namespace.jsonld
Validation Report
Conforms: True

Full toolcap exemplar also passes:

$ case_validate --built-version case-1.4.0 \
    --ontology-graph change_proposals/capability-namespace.ttl \
    --ontology-graph change_proposals/capability-namespace-shapes.ttl \
    --ontology-graph extensions/toolcap/toolcap.ttl \
    --ontology-graph extensions/toolcap/toolcap-shapes.ttl \
    --inference rdfs --allow-info \
    extensions/toolcap/toolcap-exemplar.ttl
Validation Report
Conforms: True

Unresolved issues

  • Committee should decide whether Parser should be a subclass of Module or directly of Software.
  • Committee should decide on the namespace placement for Module and Parser (uco-observable vs. new namespace).
  • The recommended kindOfRelationship vocabulary terms (hasCapability, mayUse, uses, runs-on, variation-of, isVersionOf) should be discussed for potential standardization.

Draft OWL definitions (proposed)

@prefix proposed: <https://proposed.ontology.unifiedcyberontology.org/uco/capability/> .
@prefix uco-core: <https://ontology.unifiedcyberontology.org/uco/core/> .
@prefix uco-action: <https://ontology.unifiedcyberontology.org/uco/action/> .
@prefix uco-observable: <https://ontology.unifiedcyberontology.org/uco/observable/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://proposed.ontology.unifiedcyberontology.org/uco/capability>
	a owl:Ontology ;
	rdfs:label "Proposed UCO Capability Namespace"@en ;
	rdfs:comment "Extension ontology declaring classes and properties proposed for inclusion in UCO as a new 'capability' namespace. Includes Capability (subclass of UcoObject), Module and Parser (subclasses of Software)."@en ;
	.

proposed:Capability
	a owl:Class ;
	rdfs:subClassOf uco-core:UcoObject ;
	rdfs:label "Capability"@en ;
	rdfs:comment "A capability is the ability of an entity to perform some action or produce some result. Capabilities are connected to their possessors (tools, modules, parsers, people, organizations) via uco-core:Relationship instances with kindOfRelationship='hasCapability'. A capability may be described unstructured (via name/description) or structured (via structuredCharacterization pointing to an ActionPattern). See https://github.com/ucoProject/UCO/issues/596 for related Software hierarchy work."@en ;
	.

proposed:Module
	a owl:Class ;
	rdfs:subClassOf uco-observable:Software ;
	rdfs:label "Module"@en ;
	rdfs:comment "A module is a discrete, potentially reusable component of a larger software system. In forensic tool architectures, a module represents a pluggable unit of functionality such as a parsing module, carving module, or decryption module. Modules are related to Tools via Relationship instances with kindOfRelationship='mayUse' (available but not necessarily active) or 'uses' (active in a specific configuration). See https://en.wikipedia.org/wiki/Modular_programming for the general concept."@en ;
	.

proposed:Parser
	a owl:Class ;
	rdfs:subClassOf uco-observable:Software ;
	rdfs:label "Parser"@en ;
	rdfs:comment "A parser is a type of software that takes structured or semi-structured input data and extracts meaningful content from it. In forensic contexts, parsers read application databases, file formats, and data structures to produce observable artifacts (messages, contacts, files, etc.). Parsers are typically used by Modules and are related to them via Relationship instances with kindOfRelationship='uses'. See https://en.wikipedia.org/wiki/Parsing for the general concept."@en ;
	.

proposed:structuredCharacterization
	a owl:ObjectProperty ;
	rdfs:label "structuredCharacterization"@en ;
	rdfs:comment "A structured representation of what a capability entails, expressed as an ActionPattern specifying the action type, target objects, and expected results."@en ;
	rdfs:domain proposed:Capability ;
	rdfs:range uco-action:ActionPattern ;
	.

proposed:capabilityScope
	a owl:DatatypeProperty ;
	rdfs:label "capabilityScope"@en ;
	rdfs:comment "A categorization of the capability domain (e.g., 'forensic-parsing', 'data-acquisition', 'threat-operation', 'software-assurance', 'human-skill')."@en ;
	rdfs:domain proposed:Capability ;
	rdfs:range xsd:string ;
	.

proposed:analyticFocus
	a owl:ObjectProperty ;
	rdfs:label "analyticFocus"@en ;
	rdfs:comment "The primary observable object (typically an Application) that a module is designed to analyze or process."@en ;
	rdfs:domain proposed:Module ;
	rdfs:range uco-observable:ObservableObject ;
	.

Draft SHACL shapes (proposed)

@prefix proposed: <https://proposed.ontology.unifiedcyberontology.org/uco/capability/> .
@prefix uco-core: <https://ontology.unifiedcyberontology.org/uco/core/> .
@prefix uco-action: <https://ontology.unifiedcyberontology.org/uco/action/> .
@prefix uco-observable: <https://ontology.unifiedcyberontology.org/uco/observable/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

proposed:Capability-Shape
	a sh:NodeShape ;
	sh:targetClass proposed:Capability ;
	sh:property
		[
			sh:path proposed:structuredCharacterization ;
			sh:class uco-action:ActionPattern ;
			sh:nodeKind sh:IRI ;
			sh:maxCount "1"^^xsd:integer ;
			sh:name "structuredCharacterization" ;
			sh:description "Structured ActionPattern representation of the capability (at most one)." ;
		] ,
		[
			sh:path proposed:capabilityScope ;
			sh:datatype xsd:string ;
			sh:nodeKind sh:Literal ;
			sh:name "capabilityScope" ;
			sh:description "Capability domain categorization (zero or more)." ;
		]
		;
	.

proposed:Module-Shape
	a sh:NodeShape ;
	sh:targetClass proposed:Module ;
	sh:property
		[
			sh:path proposed:analyticFocus ;
			sh:class uco-observable:ObservableObject ;
			sh:nodeKind sh:IRI ;
			sh:name "analyticFocus" ;
			sh:description "Primary analysis target of this module (zero or more)." ;
		]
		;
	.

proposed:Parser-Shape
	a sh:NodeShape ;
	sh:targetClass proposed:Parser ;
	.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions