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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ code, in your browser, your terminal, and your CI pipeline.**
The Microsoft Threat Modeling Tool (MTMT) is Windows-only, GUI-only, and can't run in a pipeline.
Threat Model Forge keeps its file format, reading and writing `.tm7` files **byte-for-byte
losslessly**, and removes everything else: author models in a browser Studio or a headless CLI,
diff and merge them like source code, validate them against **built-in security and hygiene
diff and merge them like source code, analyze them against **built-in security and hygiene
rules**, and gate a build on the result. No Windows, no GUI required.

**Try it now, no install:** the full editor and validation engine run client-side (WebAssembly) at
Expand Down Expand Up @@ -57,7 +57,7 @@ tmforge new payments.tm7 --name "Payments"
tmforge add process payments.tm7 --name "Checkout API"
tmforge add store payments.tm7 --name "Orders DB"
tmforge add boundary payments.tm7 --name "Azure VNet"
tmforge lint payments.tm7 # validate: exits 2 on findings, CI-ready
tmforge analyze payments.tm7 # analyze: exits 2 on findings, CI-ready
tmforge report payments.tm7 --out payments.html
```

Expand All @@ -77,7 +77,7 @@ open as-is; see [Formats & interoperability](docs/formats.md).
- **Convert** between `.tm7`, `tmforge-json`, draw.io, and Visio.
- **Report** to self-contained HTML (with inline SVG diagrams), or `render` the diagram right
in your terminal.
- **Validate in CI** with the `tmforge` CLI (`tmforge lint`), gating builds on SARIF-reported
- **Analyze in CI** with the `tmforge` CLI (`tmforge analyze`), gating builds on SARIF-reported
findings.

## Documentation
Expand Down Expand Up @@ -145,7 +145,7 @@ Pull the published multi-arch images from GitHub Container Registry:
docker run --rm -p 8080:8080 ghcr.io/hacks4snacks/tmforge # -> http://localhost:8080/

# CLI tool
docker run --rm -v "$PWD:/work" ghcr.io/hacks4snacks/tmforge-cli tmforge lint model.tm7
docker run --rm -v "$PWD:/work" ghcr.io/hacks4snacks/tmforge-cli tmforge analyze model.tm7
```

Published tags include `latest`, the release version (e.g. `0.1.0`), `0.1`, and `edge` (latest
Expand Down
6 changes: 3 additions & 3 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ RUN printf '#!/bin/sh\nexec dotnet /opt/tmforge/tmforge.dll "$@"\n' > /usr/local
&& chmod +x /usr/local/bin/tmforge

# Build-time smoke test: author a throwaway model and drive it through the CLI to prove the image
# runs. `report` must succeed (exit 0); `lint` must run the analysis — exit 0 (clean) or 2
# runs. `report` must succeed (exit 0); `analyze` must run the analysis — exit 0 (clean) or 2
# (findings), but not 1 (could not run).
RUN set -eu; \
tmforge new /tmp/smoke.tm7 --name smoke; \
tmforge report /tmp/smoke.tm7 --out /tmp/smoke.html; \
code=0; tmforge lint /tmp/smoke.tm7 || code=$?; [ "$code" -eq 0 ] || [ "$code" -eq 2 ]; \
code=0; tmforge analyze /tmp/smoke.tm7 || code=$?; [ "$code" -eq 0 ] || [ "$code" -eq 2 ]; \
rm -f /tmp/smoke.tm7 /tmp/smoke.html

# Default to the umbrella command's help; override with e.g. `docker run <image> tmforge lint ...`.
# Default to the umbrella command's help; override with e.g. `docker run <image> tmforge analyze`.
ENTRYPOINT ["tmforge"]
CMD ["--help"]
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ Microsoft Threat Modeling Tool (MTMT).
| Guide | What it covers |
| --- | --- |
| [Overview & features](overview.md) | Concepts, the three surfaces (CLI, Studio, API), formats, and rules at a glance. |
| [Quick start](quickstart.md) | Author, validate, and report on your first model. |
| [Quick start](quickstart.md) | Author, analyze, and report on your first model. |
| [Installation](installation.md) | Prebuilt binaries, container images, the .NET global tool, and building from source. |
| [CLI reference](cli-reference.md) | Every `tmforge` command, its options, exit codes, and JSON output. |
| [Studio guide](studio-guide.md) | Browser-based diagram authoring with the React Studio SPA. |
| [Engine API reference](api-reference.md) | The versioned `/v1` HTTP surface and its endpoints. |
| [Formats & interoperability](formats.md) | `.tm7`, `tmforge-json`, draw.io, and Visio import/export and fidelity. |
| [Validation rules & CI](validation-rules.md) | The built-in rule set, rule packs, suppressions, and gating a build. |
| [Analysis rules & CI](analysis-rules.md) | The built-in rule set, rule packs, suppressions, and gating a build. |
| [Deployment](deployment.md) | Running the engine API + Studio in containers, Kubernetes, and CI/CD. |

## The three surfaces
Expand Down
58 changes: 34 additions & 24 deletions docs/validation-rules.md → docs/analysis-rules.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Validation rules & CI
# Analysis rules & CI

Threat Model Forge ships a built-in rule set that runs against any model and flags completeness,
diagram-hygiene, and security-property issues. The same engine backs `tmforge lint`, Studio's
**Validate** button, and the API's `POST /v1/model/validate`.
diagram-hygiene, and security-property issues. The same engine backs `tmforge analyze`, Studio's
**Analyze** button, and the API's `POST /v1/model/analyze`.

## Running validation
## Running analysis

```bash
tmforge lint model.tm7 # human-readable
tmforge lint model.tm7 --json # machine-readable envelope
tmforge lint model.tm7 --reportFolder ./out # + SARIF, HTML, and JSON listing
tmforge analyze model.tm7 # human-readable
tmforge analyze model.tm7 --json # machine-readable envelope
tmforge analyze model.tm7 --reportFolder ./out # + SARIF, HTML, and JSON listing
```

### Exit codes
Expand All @@ -25,7 +25,7 @@ The dedicated `2` lets CI **fail on findings** while distinguishing them from a
### Severities

Findings carry a severity: **Error**, **Warning**, or **Info**. By default only **Error** findings set
the "found issues" exit code (`2`); pass `--max-severity warning` (or `info`) to `tmforge lint` to gate
the "found issues" exit code (`2`); pass `--max-severity warning` (or `info`) to `tmforge analyze` to gate
the build on those severities too.

## Rule packs
Expand All @@ -42,6 +42,7 @@ that declare them. List them from the API with `GET /v1/rule-packs`.
| `data-protection` | Data Protection | Data-at-rest protection: encryption, access control, integrity, retention. |
| `transport-security` | Transport Security | Data-in-transit protection across trust boundaries. |
| `identity-access` | Identity & Access | Authentication, least privilege, and access to components. |
| `availability` | Availability | Recoverability and audit-trail durability: backups for important data. |

## Built-in rules

Expand Down Expand Up @@ -72,6 +73,7 @@ snapshot. `tmforge` and the engine's `GET /v1/rules` report the live rule set.
| 1009 | Edge missing protocol description | Info | A flow mentions its protocol in the description text. |
| 1010 | Edge missing port | Warning | A flow declares a port when it can't be inferred from the protocol. |
| 1013 | Edge missing data classification | Warning | A flow declares a data classification. |
| 1029 | Unaudited boundary process | Warning | A process receiving input across a trust boundary writes to an audit-log store so its actions can be attributed. |

### Input Validation (`input-validation`)

Expand All @@ -91,6 +93,7 @@ snapshot. `tmforge` and the engine's `GET /v1/rules` report the live rule set.
| 1022 | Credentials in log store | Warning | A store recording log data does not also store credentials. |
| 1025 | Weak or unapproved cipher | Warning | A flow or store declaring an encryption algorithm uses an approved authenticated cipher (AES-GCM, AES-CBC+HMAC, or ChaCha20-Poly1305). |
| 1027 | Cached credential read | Warning | A flow reading from a credential store is not cached (`Cached=No`), so a rotated or revoked credential is not served stale. |
| 1030 | Sensitive data to external | Warning | A flow carrying sensitive data (EUII, EUPI, customer content, account data, or access-control data) is not sent to an external interactor. |

### Transport Security (`transport-security`)

Expand All @@ -107,12 +110,18 @@ snapshot. `tmforge` and the engine's `GET /v1/rules` report the live rule set.
| 1024 | Over-privileged process | Warning | A process does not run as a highly privileged account (root/admin/system). |
| 1026 | Shared static identity | Warning | A single `Identity` is not asserted by flows from 2+ distinct sources; each calling principal has its own scoped identity. |

### Availability (`availability`)

| ID | Rule | Severity | Checks |
| --- | --- | --- | --- |
| 1028 | Data store without backup | Warning | A store holding credentials or audit/log data declares a backup (`Backup=Yes`), so its contents can be recovered after loss or a destructive attack. |

## Rule help

Every finding carries the rule's **ID** (for example `TM1016`). To see what a rule checks and how to
clear it:

- **Studio**: open the **Validation** panel and click the **?** on a rule to expand its description
- **Studio**: open the **Analysis Rules** panel and click the **?** on a rule to expand its description
and fix guidance in place. That text ships with the engine, so it always matches the rule that ran.
- **CLI / API**: `GET /v1/rules` returns each rule's `description`, `helpText`, and `helpUri`, and
both the HTML report and SARIF carry the rule's `helpUri` for code-scanning dashboards.
Expand All @@ -136,37 +145,38 @@ tmforge set model.tm7 --id <process-guid> --property AuthenticationScheme=OAuth

Common rule-checked properties include `Protocol`, `Port`, `DataType` / data classification,
`AuthenticationScheme`, `SanitizesInput` / `SanitizesOutput`, `Isolation`, `AccessControl`, `Signed`,
`AuthenticatesItself`, `RunningAs`, `Algorithm`, and encryption/at-rest flags. In
[Studio](studio-guide.md), edit the same properties in the inspector and re-**Validate**.
`AuthenticatesItself`, `RunningAs`, `Algorithm`, `StoresCredentials` / `StoresLogData`, `Backup`, and
encryption/at-rest flags. In [Studio](studio-guide.md), edit the same properties in the inspector and
re-**Analyze**.

## Customizing the rule set

### Selecting rules and packs

When a model is loaded from the native **`tmforge-json`** format, any embedded validation selection
When a model is loaded from the native **`tmforge-json`** format, any embedded analysis selection
(disabled packs or rule ids) is honored automatically, so a model can carry its own policy. Other
formats (for example `.tm7`) use the full rule set unless you pass an explicit `--ruleset`.

### Custom rule set file

```bash
tmforge lint model.tm7 --ruleset ./my-ruleset.xml
tmforge analyze model.tm7 --ruleset ./my-ruleset.xml
```

### Rule variables

Some rules read variables supplied on the command line (repeatable):

```bash
tmforge lint model.tm7 --define key=value --define another=value
tmforge analyze model.tm7 --define key=value --define another=value
```

## Suppressions

Filter known/accepted findings with a suppression document:

```bash
tmforge lint model.tm7 --suppressionFile ./suppressions.json
tmforge analyze model.tm7 --suppressionFile ./suppressions.json
```

Suppressions are matched per model path and applied before evaluation, so suppressed findings don't
Expand All @@ -181,7 +191,7 @@ affect the exit code.
- **JSON listing**: a structured enumeration of the model.

```bash
tmforge lint model.tm7 --reportFolder "$CI_ARTIFACTS/threatmodel"
tmforge analyze model.tm7 --reportFolder "$CI_ARTIFACTS/threatmodel"
```

## CI integration
Expand All @@ -193,21 +203,21 @@ to your CI.
name: threat-model
on: [pull_request]
jobs:
validate:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download tmforge
run: |
curl -fsSL -o tmforge.tar.gz \
https://github.com/OWNER/REPO/releases/download/v0.1.0/tmforge-0.1.0-linux-x64.tar.gz
https://github.com/hacks4snacks/tmforge/releases/download/v0.1.0/tmforge-0.1.0-linux-x64.tar.gz
tar -xzf tmforge.tar.gz
echo "$PWD/tmforge-0.1.0-linux-x64" >> "$GITHUB_PATH"
- name: Validate threat models
- name: Analyze threat models
run: |
set -e
for model in $(git ls-files '*.tm7'); do
tmforge lint "$model" --reportFolder "reports/$(basename "$model")"
tmforge analyze "$model" --reportFolder "reports/$(basename "$model")"
done
- name: Upload SARIF
if: always()
Expand All @@ -216,11 +226,11 @@ jobs:
sarif_file: reports
```

`tmforge lint` returns `2` when a model has findings, which fails the step; `1` signals a tool error.
`tmforge analyze` returns `2` when a model has findings, which fails the step; `1` signals a tool error.
See the [deployment guide](deployment.md#cicd) for container-based pipelines.

## See also

- [CLI reference: `lint`](cli-reference.md#lint): all options.
- [Overview & features](overview.md): where validation fits.
- [Engine API reference](api-reference.md): `POST /v1/model/validate` and the catalog endpoints.
- [CLI reference: `analyze`](cli-reference.md#analyze): all options.
- [Overview & features](overview.md): where analysis fits.
- [Engine API reference](api-reference.md): `POST /v1/model/analyze` and the catalog endpoints.
14 changes: 9 additions & 5 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ and `/openapi` are matched first.
| `GET /v1/rules` | Catalog | List analysis rules. |
| `GET /v1/rule-packs` | Catalog | List rule packs. |
| `GET /v1/property-schema` | Catalog | List the typed custom-property schema the rules read. |
| `POST /v1/model/validate` | Model | Validate a model and return findings. |
| `POST /v1/model/analyze` | Model | Analyze a model and return findings. |
| `POST /v1/model/read` | Model | Parse uploaded bytes (base64) into the canonical model. |
| `POST /v1/model/convert?to=<format>` | Model | Convert a model to another format. |
| `POST /v1/model/export/tm7` | Model | Export a model as a `.tm7` file. |
Expand All @@ -55,7 +55,7 @@ curl http://localhost:8080/v1/health

```bash
curl http://localhost:8080/v1/formats # what can be read/written and how faithfully
curl http://localhost:8080/v1/rules # the validation rules
curl http://localhost:8080/v1/rules # the analysis rules
curl http://localhost:8080/v1/rule-packs # the rule packs (core-hygiene, stride-completeness, ...)
curl http://localhost:8080/v1/property-schema # typed custom properties the rules read
curl http://localhost:8080/v1/stencils # authoring stencils
Expand All @@ -65,10 +65,10 @@ curl http://localhost:8080/v1/stencils # authoring stencils

`POST /v1/detect` sniffs uploaded bytes and reports the matching format.

### Validate a model
### Analyze a model

`POST /v1/model/validate` returns findings for a supplied model, the same rule engine `tmforge lint`
uses. This is how Studio's **Validate** button overlays findings on the canvas.
`POST /v1/model/analyze` returns findings for a supplied model, the same rule engine `tmforge analyze`
uses. This is how Studio's **Analyze** button overlays findings on the canvas.

### Convert / export

Expand All @@ -79,6 +79,10 @@ uses. This is how Studio's **Validate** button overlays findings on the canvas.
# POST /v1/model/export/tm7
```

Both `.tm7` paths embed the Threat Model Forge knowledge base and write typed properties, so the
exported file opens in the Microsoft Threat Modeling Tool. See
[Formats](formats.md#tm7-and-the-microsoft-threat-modeling-tool).

### Report

`POST /v1/model/report?format=html` (or `format=svg`) renders a report from a model, the hosted
Expand Down
Loading
Loading