|
| 1 | +Metadata-Version: 2.4 |
| 2 | +Name: r3threatmodeling |
| 3 | +Version: 0.3.3 |
| 4 | +Summary: r3threatmodeling tool for structuring and reporting |
| 5 | +Author: James Brown |
| 6 | +Author-email: David Cervigni <david.cervigni@r3.com> |
| 7 | +License: Apache-2.0 |
| 8 | +Project-URL: Homepage, https://github.com/corda/threat-model-tool/ |
| 9 | +Project-URL: Bug Tracker, https://github.com/corda/threat-model-tool/issues |
| 10 | +Classifier: Development Status :: 1 - Beta |
| 11 | +Classifier: Programming Language :: Python :: 3 |
| 12 | +Classifier: License :: OSI Approved :: Apache Software License |
| 13 | +Classifier: Operating System :: OS Independent |
| 14 | +Requires-Python: >=3.10 |
| 15 | +Description-Content-Type: text/markdown |
| 16 | +License-File: LICENSE |
| 17 | +Requires-Dist: tree-node @ git+https://github.com/corda/threat-model-tool.git#subdirectory=tree-node |
| 18 | +Requires-Dist: pathvalidate |
| 19 | +Requires-Dist: pyyaml |
| 20 | +Requires-Dist: ruamel.yaml |
| 21 | +Requires-Dist: semantic-version |
| 22 | +Requires-Dist: markdown==3.7 |
| 23 | +Requires-Dist: markdown-include |
| 24 | +Requires-Dist: mkdocs |
| 25 | +Requires-Dist: cvss |
| 26 | +Requires-Dist: watchdog |
| 27 | +Requires-Dist: pyvis |
| 28 | +Requires-Dist: importlib_resources |
| 29 | +Requires-Dist: jira |
| 30 | +Requires-Dist: pikepdf |
| 31 | +Requires-Dist: pymdown-extensions |
| 32 | +Requires-Dist: beautifulsoup4 |
| 33 | +Provides-Extra: dev |
| 34 | +Requires-Dist: pytest>=7.0.0; extra == "dev" |
| 35 | +Requires-Dist: pytest-cov; extra == "dev" |
| 36 | +Requires-Dist: black; extra == "dev" |
| 37 | +Requires-Dist: flake8; extra == "dev" |
| 38 | +Requires-Dist: mypy; extra == "dev" |
| 39 | +Dynamic: license-file |
| 40 | + |
| 41 | +# Structured Threat Modeling Tools |
| 42 | + |
| 43 | +These tools enable a structured approach to threat modeling using YAML files, allowing for version control, automated report generation, and consistent security analysis across projects. |
| 44 | + |
| 45 | +## Development Setup |
| 46 | + |
| 47 | +### Option 1: Dev Container (Recommended) |
| 48 | + |
| 49 | +The easiest way to get started is by using the provided Dev Container. It comes pre-configured with all necessary tools, including **uv**, **make**, and a Python environment. |
| 50 | + |
| 51 | +**Prerequisites:** [Docker](https://www.docker.com/) and [VS Code](https://code.visualstudio.com/) with the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers). |
| 52 | + |
| 53 | +1. Clone the repo and open it in VS Code. |
| 54 | +2. When prompted, click **"Reopen in Container"** (or use the Command Palette: `Dev Containers: Reopen in Container`). |
| 55 | +3. All tools (`uv`, `make`) and dependencies are pre-installed. |
| 56 | + |
| 57 | +#### Quick Commands (via Makefile) |
| 58 | +- `make init` - Setup editable installation in the current environment. |
| 59 | +- `make test` - Run all tests using `pytest`. |
| 60 | +- `make run-example` - Generate example threat model reports from `tests/exampleThreatModels`. |
| 61 | +- `make build` - Build the project distribution packages. |
| 62 | +- `make check-yaml` - Validate all YAML files in the default directory. |
| 63 | +- `make upgrade-yaml-inplace TM_FILE=<path>` - Perform in-place schema upgrade (recursive). |
| 64 | +- `make clean` - Cleanup generated artifacts (dist, build, public). |
| 65 | + |
| 66 | +#### Debugging |
| 67 | +- Run `make debug` in a terminal. |
| 68 | +- Use the **"Python: Attach to Makefile Debugger"** configuration in VS Code to step through the execution. |
| 69 | + |
| 70 | +The dev container includes: |
| 71 | +- Python 3.12 with `uv` for fast package management. |
| 72 | +- Everything needed for PlantUML rendering and PDF generation. |
| 73 | + |
| 74 | +### Option 2: Local Development Setup (Manual) |
| 75 | + |
| 76 | +If you prefer to work outside a container, Python 3.10+ is required. We recommend using `uv` for dependency management. |
| 77 | + |
| 78 | +```bash |
| 79 | +# Clone the repository |
| 80 | +git clone https://github.com/corda/threat-model-tool.git |
| 81 | +cd threat-model-tool |
| 82 | + |
| 83 | +# Install packages in development mode |
| 84 | +uv pip install -e ./tree-node |
| 85 | +uv pip install -e . |
| 86 | +``` |
| 87 | + |
| 88 | +### Option 3: Production Installation |
| 89 | + |
| 90 | +For use in other projects, you can install directly from the repository: |
| 91 | + |
| 92 | +```bash |
| 93 | +pip install git+https://github.com/corda/threat-model-tool.git |
| 94 | +``` |
| 95 | + |
| 96 | +## Project Structure |
| 97 | + |
| 98 | +This repository contains two main packages: |
| 99 | + |
| 100 | +### 1. `tree-node/` - Standalone Tree Structure Library |
| 101 | +- **Purpose**: Reusable tree node implementation with hierarchical ID management |
| 102 | +- **Independence**: Zero dependencies, can be used in any Python project |
| 103 | +- **Features**: Parent-child relationships, tree traversal, ID validation |
| 104 | +- **Documentation**: See [tree-node/README.md](tree-node/README.md) |
| 105 | + |
| 106 | +### 3. `threat-model-tool-js/` - TypeScript/Node.js Implementation |
| 107 | +- **Purpose**: A modern port of the threat modeling library to TypeScript. |
| 108 | +- **Features**: Type-safe parsing, fast rendering, and shared logic with the Python version. |
| 109 | +- **Documentation**: See [threat-model-tool-js/README.md](threat-model-tool-js/README.md). |
| 110 | + |
| 111 | +## Building and Distribution |
| 112 | + |
| 113 | +The project uses `uv` for building. You can build both the `tree-node` library and the main `r3threatmodeling` package using: |
| 114 | + |
| 115 | +```bash |
| 116 | +make build |
| 117 | +``` |
| 118 | + |
| 119 | +This will generate `.whl` and `.tar.gz` files in the `dist/` directories of both packages. |
| 120 | + |
| 121 | +## Report Generation |
| 122 | + |
| 123 | +### Main Tool: `fullBuildSingleTM` |
| 124 | + |
| 125 | +The primary way to generate reports for a single threat model is using `fullBuildSingleTM`. |
| 126 | + |
| 127 | +```bash |
| 128 | +python -m r3threatmodeling.fullBuildSingleTM \ |
| 129 | + --rootTMYaml path/to/MySystem.yaml \ |
| 130 | + --outputDir build/generated_reports \ |
| 131 | + --generatePDF \ |
| 132 | + --template TM_templateFull |
| 133 | +``` |
| 134 | + |
| 135 | +### Available Parameters |
| 136 | + |
| 137 | +| Parameter | Type | Default | Description | |
| 138 | +|-----------|------|---------|-------------| |
| 139 | +| `--rootTMYaml` | file | required | Path to the root threat model YAML file | |
| 140 | +| `--outputDir` | path | `build` | Output directory for generated reports | |
| 141 | +| `--template` | string | `TM_template` | Template to use for report generation | |
| 142 | +| `--mainTitle` | string | auto-generated | **Optional.** Custom title for the report. | |
| 143 | +| `--generatePDF` | flag | false | Generate PDF output in addition to HTML/Markdown | |
| 144 | +| `--pdfHeaderNote` | string | `Private and confidential` | Note to include in PDF header | |
| 145 | +| `--versionsFilter` | string | - | Filter threats/assets by version (e.g., `5.0,5.1`) | |
| 146 | +| `--ancestorData` | flag | true | Include security objectives inherited from parent threat models | |
| 147 | +| `--baseFileName` | string | `{ThreatModelID}` | Custom base filename for output files | |
| 148 | +| `--visibility` | choice | `full` | Report visibility level: `full` or `public` | |
| 149 | + |
| 150 | +### Batch Generation |
| 151 | + |
| 152 | +To generate reports for all threat models in a directory (as used in `make run-example`): |
| 153 | + |
| 154 | +```bash |
| 155 | +python -m r3threatmodeling.fullBuildDirectory \ |
| 156 | + --TMDirectory threatModels/ \ |
| 157 | + --outputDir build/ |
| 158 | +``` |
| 159 | + |
| 160 | +## Schema Upgrades |
| 161 | + |
| 162 | +If you have threat models created with older versions of the schema, you can upgrade them using the normalization tool: |
| 163 | + |
| 164 | +```bash |
| 165 | +# Dry run to see changes |
| 166 | +make upgrade-yaml-dryrun TM_FILE=path/to/model.yaml |
| 167 | + |
| 168 | +# Apply changes in-place |
| 169 | +make upgrade-yaml-inplace TM_FILE=path/to/model.yaml |
| 170 | +``` |
| 171 | + |
| 172 | +## Introduction |
| 173 | + |
| 174 | +This repository provides tools to manage structured threat models as YAML files and transform them into human-readable reports (HTML, Markdown, PDF). |
| 175 | + |
| 176 | +### Example Threat Model YAML |
| 177 | + |
| 178 | +```yaml |
| 179 | +threats: |
| 180 | + - ID: VNode1.HoldingID.1 |
| 181 | + assets: |
| 182 | + - ID: HoldingID |
| 183 | + CVSS: |
| 184 | + base: 9.8 |
| 185 | + vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/MC:H/MI:H/MA:H |
| 186 | + threatType: Spoofing (caused by HoldingID collision) |
| 187 | + description: | |
| 188 | + The entropy chosen ... |
| 189 | + public: false |
| 190 | + fullyMitigated: true |
| 191 | + countermeasures: |
| 192 | + - ID: Hashing |
| 193 | + description: | |
| 194 | + Use a full SHA-256 hash ... |
| 195 | + inPlace: no |
| 196 | + - ID: UniquenessCheck |
| 197 | + description: | |
| 198 | + Check uniqueness when onboarding a virtual Node |
| 199 | + inPlace: true |
| 200 | + public: true |
| 201 | +``` |
| 202 | + |
| 203 | +Source YAML files can be found in the [threatModels](threatModels/) folder of your project. |
| 204 | + |
| 205 | +## Validation Rules |
| 206 | + |
| 207 | +The tool enforces several validation rules to ensure consistency across threat models: |
| 208 | + |
| 209 | +### Mandatory Rules |
| 210 | +- **ID and Filename Consistency**: The root `ID` field must match the filename (excluding the `.yaml` extension). |
| 211 | +- **Mandatory Scope**: Every threat model requires a non-empty `scope` section. |
| 212 | +- **Security Objective Groups**: Each `securityObjective` must have a defined `group` attribute. |
| 213 | +- **Threat Fields**: Threats must use `attack` and `impactDesc` instead of a generic `description`. They must also define `threatType` and `title`. |
| 214 | +- **Countermeasure Attributes**: Non-reference countermeasures require `inPlace` (bool), `public` (bool), `title`, and `description`. |
| 215 | +- **Asset Constraints**: Assets require a `type` and an explicit boolean `inScope` status. |
| 216 | + |
| 217 | +### Consistency Checks (Warnings) |
| 218 | +- **Mitigation Check**: `fullyMitigated` threats should have at least one `inPlace` countermeasure. |
| 219 | +- **Public Safety**: `public` threats should be `fullyMitigated`. |
| 220 | +- **Public Mitigation**: Public mitigated threats require at least one mitigation that is both `inPlace` and `public`. |
| 221 | + |
| 222 | +## AI Assistance for Threat Modeling |
| 223 | + |
| 224 | +This repository includes a specialized guide for LLM agents (like GitHub Copilot or ChatGPT) to help them understand the methodology and schema requirements of this project. |
| 225 | + |
| 226 | +The [AI Threat Modeling Guide](docs/ai/threat-modeling-guide.md) can be provided to an AI agent to: |
| 227 | +- Instruct it on the "Are we building it?" scope philosophy. |
| 228 | +- Define the strict validation rules for YAML generation. |
| 229 | +- Ensure consistent terminology and semantics across the threat model. |
| 230 | + |
| 231 | +## YAML Schema Documentation |
| 232 | + |
| 233 | +### Attackers (Roles) |
| 234 | + |
| 235 | +The `attackers` section defines the roles involved in the system. They can be trusted (`inScope: false`) or untrusted (`inScope: true`). |
| 236 | + |
| 237 | +```yaml |
| 238 | +attackers: |
| 239 | + - ID: ANONYMOUS |
| 240 | + description: | |
| 241 | + Anonymous internet user |
| 242 | + inScope: true |
| 243 | +``` |
| 244 | + |
| 245 | +### Threats |
| 246 | + |
| 247 | +A threat represents something that can go wrong. We separate the **attack** (mechanism) from the **impact** (business consequence). |
| 248 | + |
| 249 | +- `title`: Short name of the threat. |
| 250 | +- `attack`: How the threat can be exploited. |
| 251 | +- `impactDescription`: Business-level impact. |
| 252 | + |
| 253 | +### Security Objectives |
| 254 | + |
| 255 | +Security objectives (S.O.) represent high-level security goals (e.g., "Full Confidentiality"). Threats are linked to these objectives via the `impactedSecObj` or `impacts` field. |
| 256 | + |
| 257 | +```yaml |
| 258 | +securityObjectives: |
| 259 | + - ID: FULL_CIA |
| 260 | + title: Confidentiality, Integrity, and Availability |
| 261 | + description: | |
| 262 | + Ability to maintain fundamental confidentiality, integrity and availability. |
| 263 | +``` |
| 264 | + |
| 265 | +By associating a threat with a security objective, the generated reports can highlight the security gaps where objectives are not fully met by countermeasures. |
| 266 | + |
| 267 | +### Assets |
| 268 | + |
| 269 | +An asset represents any part of the system in or out of scope. Explicitly defining assets helps avoid ambiguity and ensures consistent naming. |
| 270 | + |
| 271 | +```yaml |
| 272 | + - ID: unique ID of the asset |
| 273 | + specifies: | |
| 274 | + optional reference to a more general Asset ID |
| 275 | + type: process, dataFlow, credential... |
| 276 | + title: Short title |
| 277 | + description: Detailed description |
| 278 | + inScope: true/false |
| 279 | +``` |
| 280 | + |
| 281 | +#### Asset Hierarchy |
| 282 | +Using the `specifies` keyword, an asset can be a specific instance of a more general definition (e.g., a specific API endpoint specifying a general HTTP server). This allows for inheritance of threats and countermeasures. |
| 283 | + |
| 284 | +### Versioning |
| 285 | +You can specify which versions an asset, threat, or countermeasure applies to: |
| 286 | + |
| 287 | +```yaml |
| 288 | + - ID: DF_BOOTSTRAP_TO_DB |
| 289 | + appliesToVersions: ">=5.0" |
| 290 | +``` |
| 291 | + |
| 292 | +Use the `--versionsFilter` parameter (e.g., `"--versionsFilter" "5.0,5.1"`) to filter reports by version. |
| 293 | + |
| 294 | +### Operational Hardening Guide |
| 295 | + |
| 296 | +The tool can generate a Security Hardening Guideline by collecting all operational countermeasures (`operational: true`) and grouping them by operator (e.g., `operator: ADMIN`). |
| 297 | + |
| 298 | +To make the guide readable, the title and description of an operational countermeasure should precisely answer "what the operator needs to do". |
| 299 | + |
| 300 | +```yaml |
| 301 | + countermeasures: |
| 302 | + - ID: DATA_BACKUP |
| 303 | + title: Perform data backup |
| 304 | + description: | |
| 305 | + The infrastructure operator performs regular backups... |
| 306 | + operational: true |
| 307 | + operator: INFRASTRUCTURE_OPERATOR |
| 308 | + inPlace: true |
| 309 | +``` |
| 310 | + |
| 311 | +## Proposal Marker |
| 312 | + |
| 313 | +You can mark parts of the threat model as proposals using `proposal: PROPOSAL_NAME`. The reports will highlight these sections with a special CSS class. |
| 314 | + |
| 315 | + |
| 316 | + |
| 317 | +## Threat Mitigation Status |
| 318 | + |
| 319 | +In the `threats:` section, `fullyMitigated: true` indicates that the current countermeasures (both technical and operational) are sufficient to address the threat. If a threat is only mitigated by operational steps that are not yet in place, this should be `false`. |
| 320 | + |
0 commit comments