Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ threat-forge/
│ │ ├── models/ # Rust types (serde YAML schema)
│ │ ├── stride/ # STRIDE threat engine
│ │ ├── ai/ # AI: key storage, streaming providers, system prompts
│ │ └── file_io/ # File read/write operations
│ │ ├── file_io/ # File read/write operations
│ │ └── importers/ # Import from external formats (TM7, etc.)
│ ├── Cargo.toml
│ └── tauri.conf.json
├── e2e/ # Playwright E2E tests
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Look for issues labeled [`good first issue`](https://github.com/exit-zero-labs/t
### Areas Where Help Is Needed

- **STRIDE threat rules** -- expanding the rule set for better threat coverage
- **Import/export** -- converters for Microsoft TMT `.tm7` and OWASP Threat Dragon `.json`
- **Import/export** -- OWASP Threat Dragon `.json` import, PDF export
- **Accessibility** -- keyboard navigation, screen reader support, WCAG compliance
- **Internationalization** -- translations (once i18n architecture is in place)
- **Documentation** -- tutorials, guides, example threat models
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Chat with Claude or GPT about your threat model. The AI sees your full architect

Bring your own API key. Supports Anthropic (Claude Opus 4, Sonnet 4, Haiku 3.5) and OpenAI (GPT-4o, GPT-4o Mini). Keys are AES-256-GCM encrypted at rest.

### Import from Microsoft TMT

Import existing `.tm7` files from Microsoft's Threat Modeling Tool. ThreatForge converts elements, data flows, trust boundaries, and threats to the native `.thf` format — preserving positions and STRIDE categories. No more Windows lock-in.

### Pre-built Templates

Start from six production-quality templates: **Cloud Microservices**, **E-Commerce Platform**, **Mobile Banking**, **SaaS Platform**, **IoT Smart Building**, and **Healthcare System**. Each includes a complete data flow diagram with elements, trust boundaries, data flows, and STRIDE threats.
Expand Down Expand Up @@ -155,8 +159,8 @@ Produces a native desktop binary for your platform (~10MB).
### Test

```bash
npx vitest --run # 416+ frontend tests
cargo test --manifest-path src-tauri/Cargo.toml # 59+ Rust tests
npx vitest --run # 417+ frontend tests
cargo test --manifest-path src-tauri/Cargo.toml # 73+ Rust tests
```

### Lint
Expand Down Expand Up @@ -228,7 +232,7 @@ Contributions welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instruct

Areas where help is especially valuable:
- STRIDE threat rule expansion
- Import/export (Microsoft TMT `.tm7`, OWASP Threat Dragon `.json`)
- Import/export (OWASP Threat Dragon `.json`, PDF export)
- Accessibility (WCAG compliance)
- Documentation and example threat models

Expand Down
4 changes: 3 additions & 1 deletion docs/knowledge/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ThreatForge Desktop App (Tauri v2)
│ ├── File I/O (Read/Write YAML — serde + serde_yaml)
│ ├── Schema Validation (strict serde deserialization)
│ ├── STRIDE Engine (threat rule engine)
│ ├── Importers (TM7 XML → ThreatModel conversion)
│ ├── Secure Key Storage (AES-256-GCM encrypted file)
│ ├── Auto-Updater (Tauri plugin)
│ └── Opt-in Telemetry
Expand Down Expand Up @@ -85,7 +86,8 @@ threat-forge/
│ │ ├── models/ # Rust types (serde YAML schema)
│ │ ├── stride/ # STRIDE threat engine
│ │ ├── ai/ # AI: key storage, streaming providers, system prompts
│ │ └── file_io/ # File read/write operations
│ │ ├── file_io/ # File read/write operations
│ │ └── importers/ # Import from external formats (TM7, etc.)
│ ├── Cargo.toml
│ └── tauri.conf.json
├── e2e/ # Playwright E2E tests
Expand Down
5 changes: 3 additions & 2 deletions docs/knowledge/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ThreatForge's differentiation is the combination of three things no other tool b

1. **UX gap filled** — A modern, keyboard-shortcut-driven interface with drag-and-drop canvas, 44 typed components + text annotations, custom themes, and resizable panes. The kind of experience developers expect from tools like Linear, Figma, or VS Code.

2. **File format gap filled** — The `.thf` YAML format is human-readable, git-diffable, and reviewable in pull requests. Microsoft's `.tm7` is binary. Threat Dragon's JSON is verbose. Neither can be opened in a text editor and understood.
2. **File format gap filled** — The `.thf` YAML format is human-readable, git-diffable, and reviewable in pull requests. Microsoft's `.tm7` is binary. Threat Dragon's JSON is verbose. Neither can be opened in a text editor and understood. ThreatForge can import `.tm7` files directly, converting them to `.thf` with all elements, flows, boundaries, and threats preserved.

3. **AI integration gap filled** — An integrated AI chat pane (BYOK) for conversational threat analysis and iterative model refinement. No other desktop tool combines interactive modeling with native AI assistance.

Expand All @@ -40,9 +40,10 @@ ThreatForge is production-ready. The core application is fully functional:
- STRIDE threat engine with auto-generated threats per element
- AI chat pane (BYOK) with OpenAI + Anthropic support, model selector, persistent chat sessions, markdown rendering, stop generating
- `.thf` YAML file format with clean git diffs
- Import from Microsoft TMT `.tm7` files with full element, flow, boundary, and threat conversion
- 13+ themes (light and dark), resizable panes, keyboard shortcuts, command palette
- Onboarding system with interactive guides
- 416+ frontend tests, 59+ Rust tests, 40+ E2E tests
- 417+ frontend tests, 73+ Rust tests, 40+ E2E tests
- Cross-platform via Tauri v2 (macOS, Windows, Linux)

**Remaining for public launch:** Cross-platform CI builds + code signing, auto-updater, landing page/website, launch marketing.
Expand Down
3 changes: 2 additions & 1 deletion docs/knowledge/product-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@
| Author tracking | Name/email settings, auto-populated created_by/modified_by |
| Self-loop connectors | Data flows from a node to itself |
| Canvas panning | Arrow key nudge for elements, arrow key pan when nothing selected |
| Import from MS TMT (.tm7) | XML parser converts elements, flows, boundaries, threats to `.thf` with positions preserved |

### Should-Have (future)

| Feature | Priority |
|---------|----------|
| Import from MS TMT (.tm7) and Threat Dragon (.json) | P0 |
| Import from Threat Dragon (.json) | P0 |
| PDF/HTML export for stakeholders | P1 |
| LINDDUN privacy methodology support | P2 |
| Multiple diagrams per model | P2 |
Expand Down
48 changes: 48 additions & 0 deletions docs/plans/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,54 @@ Shared execution plan for humans and LLM agents. Update this file before, during

---

## 2026-03-07 — Import TM7 and Other File Formats

### Plan
- [x] 1. Rust: TM7 XML parser module (`src-tauri/src/importers/`)
- [x] Add `quick-xml` crate to `Cargo.toml`
- [x] Create `src-tauri/src/importers/mod.rs`
- [x] Create `src-tauri/src/importers/tm7.rs` — parse TM7 XML → `ThreatModel`
- [x] Unit tests for TM7 parsing (6 tests: minimal TM7, empty TM7, unique IDs, STRIDE categories, severity, mitigation status)
- [x] 2. Rust: Tauri command for import
- [x] Create `src-tauri/src/commands/import_commands.rs` with `import_threat_model` command
- [x] Register command in `lib.rs`
- [x] 3. Frontend: Import flow
- [x] Add `importModel` to `useFileOperations` hook
- [x] Add "Import…" menu item to native menu (`menu.rs`)
- [x] Handle `file-import` menu event in `useNativeMenu`
- [x] Add import command to command palette (`command-registry.ts`)
- [x] Update `FileAdapter` with `importThreatModel` method
- [x] Implement in `TauriFileAdapter` with open dialog for `.tm7` files
- [x] Browser adapter stub (shows "desktop only" alert)
- [x] 4. Validation (initial)
- [x] `cargo clippy` — clean
- [x] `npx biome check --write .` — clean
- [x] `cargo test` — 69 tests pass (10 new)
- [x] `npx vitest --run` — 417 tests pass (1 new)
- [x] `cargo fmt` — clean
- [x] 5. Deep audit & fixes
- [x] Fix `parse_stencil_properties` stale `current_display_name` bug — clear after consuming Value
- [x] Fix `NeedsInvestigation` mapped to `InProgress` → should be `NotStarted`
- [x] Fix dead code in `TauriFileAdapter.openThreatModel` — redundant ternary
- [x] Add test: malformed XML returns error
- [x] Add test: `NeedsInvestigation` maps to `NotStarted`
- [x] Add test: unknown STRIDE TypeId prefix falls back to Tampering
- [x] Add test: self-loop flow (from == to) imported correctly
- [x] Update README.md — add "Import from Microsoft TMT" to Features, fix Contributing
- [x] Update CONTRIBUTING.md — TM7 import done, only Threat Dragon remains
- [x] Update overview.md — add import to status list, update test counts
- [x] Update product-design.md — move TM7 import to Must-Have table
- [x] Final validation: clippy clean, biome clean, 73 Rust tests, 417 frontend tests
- [ ] Manual test with a real TM7 file

### Notes
- TM7 is Microsoft's XML-based format with .NET serialization artifacts
- Architecture is extensible — `importers/` module can support future formats (Threat Dragon JSON, OTMF, etc.)
- Import produces a ThreatModel that the user must "Save As" to create a .thf file
- Deep audit found and fixed: stale state bug in property parser, incorrect mitigation mapping, dead code, missing tests, outdated docs

---

## 2026-03-03 — AI Chat Pane Improvements

### Plan
Expand Down
1 change: 1 addition & 0 deletions docs/runbooks/releasing-a-version.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Monitor the workflow at: `Actions > Release > v0.2.0`
2. Download binaries for each platform and smoke test:
- App launches without errors
- Can create, save, and reopen a `.thf` file
- Import a `.tm7` file (File > Import) — elements, flows, boundaries, and threats appear on canvas
- AI chat works (with valid API key): model selector, chat sessions, stop generating, markdown rendering
- STRIDE analysis runs
3. Publish the draft release (click "Publish release" on GitHub)
Expand Down
12 changes: 11 additions & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ schemars = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
quick-xml = "0.37"
thiserror = "2"
uuid = { version = "1", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }
Expand Down
15 changes: 15 additions & 0 deletions src-tauri/src/commands/import_commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::importers::tm7;
use crate::models::ThreatModel;
use std::path::PathBuf;

#[tauri::command]
pub fn import_threat_model(path: String, format: String) -> Result<ThreatModel, String> {
let path = PathBuf::from(&path);
let contents =
std::fs::read_to_string(&path).map_err(|e| format!("Failed to read file: {e}"))?;

match format.as_str() {
"tm7" => tm7::parse_tm7(&contents).map_err(|e| e.to_string()),
_ => Err(format!("Unsupported import format: {format}")),
}
}
2 changes: 2 additions & 0 deletions src-tauri/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod ai_commands;
mod file_commands;
mod import_commands;
mod stride_commands;
mod update_commands;

pub use ai_commands::*;
pub use file_commands::*;
pub use import_commands::*;
pub use stride_commands::*;
pub use update_commands::*;
1 change: 1 addition & 0 deletions src-tauri/src/importers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod tm7;
Loading