-
Notifications
You must be signed in to change notification settings - Fork 1
features
- 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).
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.
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.
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.
-
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 (
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: HIGHThe 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 examples/threat-model.yml for the example workflow to copy into your repo.
-
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[~].
- 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.
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.
- 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.