Skip to main content

Schema Design Principles

⚠️🚧 Work in Progress
This document is a work in progress. Content may change, and some sections may be incomplete.

The schema layer is the foundation that enables runtime validation in the ATT&CK Data Model. The design of these schemas reflects careful consideration of competing concerns: STIX compliance, ATT&CK domain rules, and TypeScript integration. This page explores the principles of our schema design decisions.

Core Design Philosophy

Rather than maintaining separate documentation about data format requirements, the schemas encode these requirements directly. This ensures that documentation stays synchronized with implementation and provides immediate feedback when requirements change.

This approach means that anyone using the schemas we provide automatically has access to ATT&CK requirements through validation feedback, rather than needing to consult separate documentation.

Schema Stack

ATT&CK schemas reflect the nature of STIX + ATT&CK requirements. This enables them to be built on a solid foundation while supporting interesting use cases on top of it.

This diagram reflects how higher-level consumers rely on TypeScript types and the schema layer, which itself composes ATT&CK-specific rules on top of the STIX core.

┌───────────────────────────────────────────────────────────────┐
│ Application / Consumers │
│ - UI and validation │
│ - e.g. ATT&CK Workbench, ATT&CK Navigator │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐
│ TypeScript Types & Runtime APIs │
│ - static types, helpers, IDE integration │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐
│ Schema Layer (zod) │
│ - ATT&CK Spec as code │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐
│ ATT&CK Specific Requirements │
│ - x_mitre_* properties, ATT&CK-specific objects │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐
│ STIX Core Requirements │
│ - id, type, spec_version, created, modified, etc. │
│ - solid foundation to build on │
└───────────────────────────────────────────────────────────────┘

ATT&CK STIX Architecture

The following interactive diagram shows how different ATT&CK STIX object types relate to each other. Hover over or click any node to explore its connections.

ATT&CK STIX Architecture

Click nodes to explore relationships • Drag nodes to rearrange • Drag canvas to pan

tactic_refskill_chain_phasessubtechnique-ofusesusesusesusesusesattributed-tomitigatesdetectsanalytic_refslog_source_refsx_mitre_data_source_ref (deprecated)detects (deprecated)targets
Matrix
x-mitre-matrix
Tactic
x-mitre-tactic
Technique
attack-pattern
Sub-technique
attack-pattern
Mitigation
course-of-action
Detection Strategy
x-mitre-detection-strategy
Analytic
x-mitre-analytic
Data Component
x-mitre-data-component
Data Source (deprecated)
x-mitre-data-source
Group
intrusion-set
Campaign
campaign
Software
malware/tool
Asset
x-mitre-asset

Click on any node to see its connections

Structure
Attack Patterns
Actors & Tools
Defense
Detection
Targets

Schema Tiers

Each ATT&CK object type that supports refinements exports up to three schema tiers, each serving a different purpose:

┌─────────────────────────────────────────────────────────────┐
│ campaignSchema (full validation) │
│ ├── Object shape (fields, types, strictness) │
│ └── Refinements (cross-field business rules) │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ campaignBaseSchema (shape only, no refinements) │
│ └── Supports .partial(), .pick(), .omit() │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ campaignPartialSchema (all fields optional) │
│ ├── Derived from base via .partial() │
│ └── Refinements re-applied (partial-safe) │
└─────────────────────────────────────────────────────────────┘
TierExampleRefinementsUse case
FullcampaignSchemaYesValidating complete ATT&CK objects
BasecampaignBaseSchemaNoDeriving custom schemas via .partial(), .pick(), .omit()
PartialcampaignPartialSchemaYes (partial-safe)Validating incomplete or draft objects

Why base schemas exist

Zod does not allow .partial(), .pick(), or .omit() on schemas that contain refinements, because these operations change the input type and the original refinement may no longer be valid. Base schemas provide the object shape without refinements, so you can safely derive custom schemas from them.

See the Schema Variants how-to guide for practical usage examples.