Features
July 14, 2026 · View on GitHub
Core Analysis
- Markdown-based Threat Modeling: Use a simple DSL to describe your architecture and flows.
- Automated STRIDE Analysis: Detects threats for each element and flow via the pytm rule engine.
- MITRE ATT&CK Mapping: Each threat is mapped to relevant MITRE tactics and techniques.
- CAPEC + CVE correlation: CVE definitions link real vulnerabilities to CAPEC patterns and MITRE techniques.
- Severity Calculation: Customizable scoring (base score per STRIDE category, protocol adjustments, data classification multipliers).
VEX — Vulnerability Exploitability eXchange
SecOpsTM uses VEX as the single authoritative CVE source, with the following priority chain applied per asset during severity scoring:
- Standalone VEX file/directory — declare
vex_file=./path/to/vex.jsonorvex_directory=./VEX/in## Context; or auto-discovered asVEX/subdirectory orvex.jsonsibling of the model file. - BOM with
analysis.state— CycloneDX BOM files that embed VEX assertions produceactive_cvesandfixed_cveswithout a separate file. - BOM
known_cveswithout state — treated as active (legacy / scanner-generated BOMs). cve_definitions.yml— fallback YAML definitions managed manually.
Fixed/resolved CVEs (from VEX or BOM state) act as a D3FEND-equivalent mitigation signal, reducing severity for patched vulnerabilities without requiring manual updates to implemented_mitigations.txt.
AI-Enhanced Threat Analysis
Three independent threat engines feed into a unified, deduplicated output:
| Engine | Source tag | Scope |
|---|---|---|
| pytm rule engine | pytm | Per element/dataflow, rule-based |
| Component-level LLM | AI | Per component, generated by the configured LLM |
| RAG pipeline | LLM | System-level, ChromaDB + HuggingFace embeddings |
- Deduplication: When an AI threat and a pytm threat cover the same (target, STRIDE category, similar description), the AI version wins. Uses offline Jaccard word-overlap — no internet required.
- Unified severity scoring: All three sources pass through the same
SeverityCalculatorbefore reporting. - Multi-provider: Ollama (fully offline), Google Gemini, OpenAI, Mistral, and any LiteLLM-compatible provider. Configured in
config/ai_config.yaml. - Offline-first: The embedding model (all-MiniLM-L6-v2) and the vector store (ChromaDB) run locally. The only outbound traffic is the LLM API call if using a cloud provider.
- Boundary-level AI threats: Trust boundaries (
SecOpsBoundary) are included as AI analysis targets, generating threats specific to boundary crossing, privilege escalation, and lateral movement. - Cross-model RAG analysis: In project mode, the RAG pipeline receives the full project context (main model + all sub-models) for cross-boundary threat detection that individual model analysis cannot surface.
- Trust context in prompts: Each component prompt includes its boundary's trust level (
TRUSTED/UNTRUSTED) so the LLM can tailor threat scenarios to the actual exposure level. - Configurable parallelism: Component-level AI enrichment runs concurrently, controlled by
max_concurrent_ai_requestsinconfig/ai_config.yamlunderthreat_generation:. Set to1for Gemini free tier (15 RPM),3–5for paid plans or Ollama. - AI config validation: On startup,
AIServicevalidatesai_config.yamland logs explicit warnings for missingmodelfields, no enabled provider, or invalid values. Degradation is always graceful — no exception is raised. - Per-component AI threat cache (
AIThreatCache): Results are cached in.secopstm_ai_cache.jsonnext to the model file, keyed by SHA-256 of the component's full detail dict. On re-analysis: only components whose attributes changed call the LLM. A 15-component model goes from ~90 s to ~6 s when unchanged. Cache is committable and shareable across team members and CI runs. Version field ensures stale v0 caches are discarded cleanly. - DSL AI context keys:
project_description,compliance_requirements,integrations, and other context keys are now declared directly in the DSL## Contextsection instead of a globalconfig/context.yaml. Per-modelcontext/*.yamlfiles are also supported for larger projects.
Goal-Driven Attack Flows (GDAF)
GDAF is a top-down attack scenario generator that works from attacker objectives and actor profiles through the system graph, assigning MITRE ATT&CK techniques to each hop. It complements the bottom-up AttackChainAnalyzer (which starts from threats) by answering: "What path would a specific adversary take to reach this target?"
- Objective-driven: Define business-impact objectives (
OBJ-DOMAIN-COMPROMISE,OBJ-FINANCIAL-EXFIL, etc.) and threat actor profiles in a YAML context file. - Graph traversal: BFS from actor entry points to target assets. Entry points are selected automatically based on trust boundaries (
internet-facing/insider/supply-chainpreference). - Per-hop MITRE techniques:
AssetTechniqueMapperscores techniques fromenterprise-attack.jsonusing platform match, asset-specific primary tactics, hop position (entry / intermediate / target), actor known TTPs, and vulnerability signals (no auth, no encryption, no MFA, legacy). - Risk scoring:
path_score = mean(hop_scores) + target_CIA_bonus. Risk levels: CRITICAL ≥ 4.0, HIGH ≥ 2.8, MEDIUM ≥ 1.8, LOW < 1.8. - Output: One
.afbAttack Flow file per scenario +gdaf_summary.json. Files are valid for import in the Attack Flow Builder. - GDAF in the HTML report: GDAF scenarios appear in the HTML threat report as a collapsible
<details>accordion (closed by default), placed after the Attack Chain Analysis section. The table shows Risk level (CRITICAL/HIGH/MEDIUM/LOW badge), Objective, Actor and sophistication, Attack Path (A → B → C), Score, Hop count, and Detection coverage. Each row is expandable to show per-hop details: node name, asset type, protocol, cleartext/no-auth flags, and assigned MITRE ATT&CK techniques. - Project mode: In multi-model projects, the attack graph spans all sub-models. Servers with
submodel=references get bridging edges so paths can traverse into component internals. - Fully offline: Only reads
enterprise-attack.jsonfrom disk — no network calls. - Red/Blue adversarial debate (opt-in,
debate.enabledinai_config.yaml, on by default): the top GDAF scenarios are stress-tested by two LLM personas — Red attempts to advance the attack, Blue counters with SIEM/EDR/IDS controls and detection gaps, grounded only in facts already in the model. The outcome adjusts each scenario's score/risk_level (never invents new threats), and the.afbfiles are re-written to match.
See docs/gdaf.md for the complete reference including the context YAML schema, scoring algorithm, debate mechanics, and asset type table.
Reporting & Export
- HTML report: Integrated threat statistics, STRIDE/MITRE mapping, D3FEND mitigations, severity breakdown, source tagging (
pytm/AI/LLM), risk signals (CVE,CWE⚠,NET,D3F), executive summary with KPIs + top-5 risks, interactive severity filter (CRITICAL/HIGH/MEDIUM/LOW), risk matrix 5×5.
Screenshots: risk matrix · top-5 threats · threat graph · CISO briefing - SOC Analyst detection pass: Per-threat Sigma / Splunk SPL / KQL rule suggestions and IOCs, generated by a dedicated LLM persona and rendered in the report's "SOC Analysis" section. Requires AI enabled; skipped silently offline.
- CISO Triage: Board-level risk briefing summarizing the highest-priority threats (including GDAF scenarios and debate outcomes when available), generated by a dedicated LLM persona.
- Executive View toggle: A single click hides all technical sections (Attack Chain Analysis, GDAF Scenarios, ATT&CK ID Validation, Threat Graph, Severity Calculation, Legend) for clean management presentations. Implemented as a pure CSS
.exec-viewclass toggle — no layout reflow. - Copy-as-ticket button: Each top-5 threat row has a "Copy ticket" button that copies a GitHub Issue–formatted markdown block to clipboard (title, severity, STRIDE category, target, description, action checklist). Supports Clipboard API with
execCommandfallback. - Collapsible report sections:
📋 Model Completenessand📖 Severity Calculation Explainedare wrapped in<details class="collapse-details">— collapsed by default to reduce visual noise, summary line visible when closed. - ⛓️ Attack Chain Analysis: Dedicated section in the HTML report identifying multi-step attack paths that chain threats across dataflows. Each chain shows entry point, pivot component, attack scores, and CRITICAL/HIGH/MEDIUM/LOW severity label.
- GDAF scenarios accordion: GDAF attack scenarios are embedded in the HTML report as an expandable section between Attack Chain Analysis and Severity Calculation Explained. Only shown when GDAF scenarios have been generated (requires a valid context YAML with
attack_objectivesandthreat_actors). - 🔍 Automatically Discovered Attack Paths: Best (highest-severity) attack path per STRIDE category, found by following each threat's MITRE ATT&CK tactic progression through the architecture — no GDAF context needed, works from the threat data alone (pytm + AI + LLM sources together). With AI enabled, each path also gets a short grounded narrative and business-impact summary (opt-out via
attack_flows.include_narrativeinai_config.yaml); the persona is instructed to never cite an ID (ATT&CK/CVE/CAPEC/D3FEND) — the exact IDs are already shown deterministically next to each hop, and any response that emits one anyway is discarded rather than trusted. - Report diff page (
/diff): Web page served at/diffthat accepts two JSON exports (paste or file upload) and displays a visual comparison — new threats[+], resolved threats[-], severity changes[~]— with counts by category at the top. Also available via CLI:secopstm --diff old_report.json new_report.json. - Versioned JSON export (
schema_version: "1.0"): Stable structure for SIEM, dashboards, and ticketing tools. Schema defined atthreat_analysis/schemas/v1/threat_model_report.schema.json. Threats carry stable IDs (T-0001). - JSON export REST API (
POST /api/export_json): Returns the versioned JSON report directly from the API without generating a ZIP bundle. Accepts{"markdown_content": "..."}and returns the schema-validated report. - STIX 2.1 bundle and ATT&CK Navigator layer (JSON).
- Attack Flow
.afbfiles for key STRIDE objectives and GDAF scenarios. - Remediation Checklist: CSV export of all actionable mitigations, one row per threat-technique pair.
- Visual Diagrams: DOT, SVG, and interactive HTML with threat highlights.
- Trust Boundary Colors: Trusted zones rendered green solid (
#2e7d32), untrusted zones red dashed (#c62828) — baked into the DOT template and exported SVG. - Severity Heat Map Overlay: Interactive toggle in diagram HTML. Applies per-component severity colour (CRITICAL → red, HIGH → orange, MEDIUM → yellow, LOW → teal) over the original diagram; hover tooltip shows severity + "View threats →" deep-link to the HTML report.
- Sub-model Drill-down: Server nodes with a
submodel=reference become hyperlinks in the parent diagram. Clicking navigates to the child diagram, which shows the server's internal architecture plus a ghost cluster of external connections from the parent model.
- Trust Boundary Colors: Trusted zones rendered green solid (
GitHub Action
SecOpsTM ships as an official GitHub Action (action.yml) for threat-modeling-as-code CI/CD:
- uses: your-org/secopstm@v1
with:
model-file: threatModel_Template/threat_model.md
output-format: json
fail-on: HIGH
The Action installs SecOpsTM, runs analysis, and optionally fails the workflow if threats at or above the specified severity level are found. Compatible with the CI/CD gate mode (--gate, --baseline, --fail-on, --accepted-risks).
See .github/workflows/threat-model.yml for the example workflow.
CLI & CI Integration
secopstmcommand: Installed viapip install -e .. No server required.secopstm --model-file model.md --stdout # JSON on stdout secopstm --model-file model.md --output-format json --output-file report.json secopstm --model-file model.md --output-format stix secopstm --server # launch web editor--output-format {all,html,json,stix}: Control which artifacts are generated.--stdout: Print the JSON report to stdout — pipe directly tojq, upload to a SIEM, or fail a CI gate on critical threat count.--diff old.json new.json: Compare two JSON exports on the command line. Prints new threats[+], resolved threats[-], and severity changes[~].
Interactive Web Editor
- Real-time Editing: Live diagram preview that updates as you type.
- DSL Validation: A validation banner below the editor updates after the last keystroke (1.2 s debounce). Turns red on structural errors, orange on warnings; also reports the number of components detected. A
_diagramInFlightconcurrency guard prevents concurrent pytm TM instantiation; the server returns{skipped: true}for overlapping validation calls (silently ignored by the client). - DSL Autocomplete: Context-aware completion dropdown on every editor instance — suggests section headers (
## Boundaries, …), attribute names (boundary=,type=, …), static values (HTTPS,database, …), and dynamic names (boundary/actor/server names from the current editor content). Trigger with any keypress or Ctrl+Space; navigate with arrows; confirm with Tab/Enter; dismiss with Escape. dsl_schema.js— single source of truth: All DSL sections, entity field definitions, autocomplete metadata, and valid values live instatic/js/dsl_schema.js. Adding a field to the schema automatically updates both the Component Panel form and the autocomplete suggestions — no other changes needed.- Component Panel (DSL Helper): A discreet
✏ Helperbutton in the editor toolbar opens a 272 px slide-in overlay panel. Provides tabbed forms for all five entity types (Boundary / Actor / Server / Dataflow / Data). Add mode generates a correctly-formatted DSL line and inserts it under the matching## Section. Edit mode populates the form from the current editor content (dropdown of existing component names), then finds and replaces the entity line on "Update". Boundary/node dropdowns auto-populate from the live editor content. - localStorage autosave: Editor content is saved to
localStorage1 s after each change (per-tab key). On next visit, an inline dismissable banner offers to restore the draft or discard it. - Interactive Diagrams: Click to highlight, interactive legend (filter by protocol), sub-model navigation.
- Severity Heat Map: Toggle button in diagram HTML applies colour-coded severity overlay; tooltip links directly to the threat report anchor for that component.
- Project Mode: Tabbed interface for multi-file projects; "Generate All" produces unified, cross-linked reports with cross-model RAG analysis.
- Load Project button (Simple Mode): The "📂 Load Project" button opens a directory picker. It automatically reads all
.mdfiles into editor tabs and detectsBOM/andcontext/subdirectories. When found, BOM ✓ and Context ✓ badges appear next to the button, and BOM/context files are sent to the server automatically on "Generate All". No manual path entry required. - Graphical Editor: Visual drag-and-drop canvas for building models without writing Markdown.
- Reports are fully self-contained and work offline.
System Model Templates
Ready-to-use DSL templates in threatModel_Template/:
| Template | Servers | Threats (offline) | Notable coverage |
|---|---|---|---|
| Kubernetes / Helm Cluster | 14 | 78 | Container escape, ServiceAccount theft, etcd exfiltration, supply chain |
| Serverless AWS Lambda | 21 | 106 | IAM escalation, SSRF to metadata, S3 misconfiguration, event injection |
| Six-Tier Web App | 15+ | — | Classic N-tier with DMZ, CDN, DB |
| Microservices Architecture | 20+ | — | Service mesh, message broker, API gateway |
| Cloud Native | 16+ | — | EKS/GKE, object storage, managed identity |
| CI/CD Pipeline | 12+ | — | SCM, build agents, registry, deployment targets |
| Mobile Application | 10+ | — | Mobile client, backend, push, biometric |
| Traditional Enterprise Network | 18+ | — | AD, VPN, DMZ, OT/IT boundary |
| On-Prem Enterprise Network | 25+ | — | Full on-prem with BOM and GDAF context |
Each template with cloud/container workloads includes a context/gdaf_context.yaml with GDAF attack objectives and threat actor profiles.
Extensibility
- PyTM Compatibility: Supports PyTM's model structure and can be extended with PyTM's features.
- IaC Plugins: Ansible (inventory + playbook parsing). Plugin architecture supports adding new IaC sources.
- Terraform (
TerraformPlugin):threat_analysis/iac_plugins/terraform_plugin.py. Parses.tffiles andterraform.tfstate; covers 50+ AWS, Azure, and GCP resource types. Currently usable via the Python API; CLI integration in progress.
- Terraform (
- Custom MITRE Mappings: Override or extend the built-in CAPEC→ATT&CK mapping.
- All mappings and calculations are modular and easy to override.