Skip to content

Quick Start

This guide walks you through creating your first threat model diagram.

1. Define a Threat Model

Threat Model Spec supports two JSON formats:

  • ThreatModel — Canonical format with shared metadata and multiple diagram views (recommended)
  • DiagramIR — Single-diagram format for simpler use cases

The ThreatModel format is the canonical representation, containing shared metadata, framework mappings, and multiple diagram views:

threat-model.json
{
  "id": "websocket-localhost-takeover",
  "title": "WebSocket Localhost Takeover",
  "description": "Malicious website exploits localhost WebSocket to compromise AI agent",
  "mappings": {
    "mitreAttack": [
      {"tacticId": "TA0001", "techniqueId": "T1189", "techniqueName": "Drive-by Compromise"}
    ],
    "owasp": [
      {"category": "api", "id": "API2:2023", "name": "Broken Authentication"}
    ]
  },
  "diagrams": [
    {
      "type": "attack-chain",
      "title": "Attack Chain",
      "elements": [
        {"id": "attacker", "label": "Attacker", "type": "external-entity"},
        {"id": "browser", "label": "Victim Browser", "type": "browser"},
        {"id": "agent", "label": "AI Agent", "type": "agent"}
      ],
      "attacks": [
        {"step": 1, "from": "attacker", "to": "browser", "label": "Serve malicious page", "mitreTechnique": "T1189"},
        {"step": 2, "from": "browser", "to": "agent", "label": "WebSocket to localhost:9999"}
      ],
      "targets": [
        {"elementId": "agent", "impact": "Full agent compromise"}
      ]
    }
  ]
}

DiagramIR Format (Single Diagram)

For simpler use cases, you can use the single-diagram format:

attack.json
{
  "type": "attack-chain",
  "title": "WebSocket Localhost Takeover",
  "description": "Malicious website exploits localhost WebSocket to compromise AI agent",
  "mappings": {
    "mitreAttack": [
      {
        "tacticId": "TA0001",
        "tacticName": "Initial Access",
        "techniqueId": "T1189",
        "techniqueName": "Drive-by Compromise"
      }
    ],
    "owasp": [
      {
        "category": "api",
        "id": "API2:2023",
        "name": "Broken Authentication"
      }
    ]
  },
  "elements": [
    {"id": "attacker", "label": "Attacker", "type": "external-entity"},
    {"id": "browser", "label": "Victim Browser", "type": "browser"},
    {"id": "agent", "label": "AI Agent", "type": "agent"}
  ],
  "attacks": [
    {
      "step": 1,
      "from": "attacker",
      "to": "browser",
      "label": "Serve malicious page",
      "mitreTechnique": "T1189"
    },
    {
      "step": 2,
      "from": "browser",
      "to": "agent",
      "label": "WebSocket to localhost:9999",
      "mitreTechnique": "T1557"
    }
  ],
  "targets": [
    {
      "elementId": "agent",
      "impact": "Full agent compromise, data exfiltration"
    }
  ]
}

2. Generate D2 Diagram

Use the tms CLI to generate a D2 diagram:

tms generate attack.json -o attack.d2

This creates a D2 file that can be rendered with the D2 CLI.

3. Render to SVG

Add the --svg flag to also render the diagram to SVG:

tms generate attack.json -o attack.d2 --svg

This creates both attack.d2 and attack.svg.

4. Validate Your Model

Validate a threat model JSON file:

tms validate attack.json
# Output: Validation passed: attack.json

Use strict validation for additional checks:

tms validate attack.json --strict

5. Export to STIX 2.1

Export your threat model to STIX 2.1 format for sharing:

tms generate attack.json --stix -o attack.stix.json

Diagram Types

Threat Model Spec supports three diagram types:

Type Use Case Key Fields
dfd Data Flow Diagrams elements, boundaries, flows
attack-chain Attack sequences elements, attacks, targets
sequence Time-ordered messages actors, messages, phases

Data Flow Diagram (DFD)

{
  "type": "dfd",
  "title": "System Architecture",
  "elements": [
    {"id": "user", "label": "User", "type": "external-entity"},
    {"id": "web", "label": "Web Server", "type": "process"},
    {"id": "db", "label": "Database", "type": "datastore"}
  ],
  "boundaries": [
    {"id": "dmz", "label": "DMZ", "type": "network", "elements": ["web"]}
  ],
  "flows": [
    {"from": "user", "to": "web", "label": "HTTPS Request"},
    {"from": "web", "to": "db", "label": "SQL Query"}
  ]
}

Sequence Diagram

{
  "type": "sequence",
  "title": "Attack Sequence",
  "actors": [
    {"id": "attacker", "label": "Attacker", "malicious": true},
    {"id": "victim", "label": "Victim"}
  ],
  "messages": [
    {"from": "attacker", "to": "victim", "label": "Phishing email", "type": "attack"},
    {"from": "victim", "to": "attacker", "label": "Credentials", "type": "exfil"}
  ]
}

Next Steps