|
| 1 | +--- |
| 2 | +name: tm7-threat-model |
| 3 | +description: Creates valid Microsoft Threat Modeling Tool (.tm7) files compatible with Microsoft Threat Modeling Tool v7.3+. Use this skill whenever asked to create, generate, or modify a .tm7 threat model file, or when performing STRIDE threat modeling that should output a .tm7 file. |
| 4 | +--- |
| 5 | + |
| 6 | +# Microsoft Threat Modeling Tool (.tm7) File Format Guide |
| 7 | + |
| 8 | +## CRITICAL: Serialization Format |
| 9 | + |
| 10 | +TM7 files use **WCF DataContractSerializer XML format**, NOT standard XML. The Microsoft Threat Modeling Tool (v7.3+) **cannot deserialize** files that use generic XML structure. If the format is wrong, the tool will show: |
| 11 | + |
| 12 | +> "File is not an actual threat model or the threat model may be corrupted." |
| 13 | +
|
| 14 | +## Required Root Element and Namespaces |
| 15 | + |
| 16 | +The file MUST start with this exact root element (NO XML declaration, NO `<?xml?>` header): |
| 17 | + |
| 18 | +```xml |
| 19 | +<ThreatModel xmlns="http://schemas.datacontract.org/2004/07/ThreatModeling.Model" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> |
| 20 | +``` |
| 21 | + |
| 22 | +**NEVER use:** |
| 23 | +- `<?xml version="1.0" encoding="utf-8"?>` — this causes deserialization failure |
| 24 | +- `xmlns:xsi` or `xmlns:xsd` — these are standard XML namespaces, NOT DataContract namespaces |
| 25 | +- Custom `<MetaInformation>`, `<SecurityGaps>`, `<Mitigations>` — these elements do NOT exist in the TM7 schema |
| 26 | + |
| 27 | +## Required Namespace Prefixes |
| 28 | + |
| 29 | +All elements MUST use proper DataContract serialization namespaces: |
| 30 | + |
| 31 | +| Prefix | URI | Used For | |
| 32 | +|--------|-----|----------| |
| 33 | +| (default) | `http://schemas.datacontract.org/2004/07/ThreatModeling.Model` | Root ThreatModel | |
| 34 | +| `xmlns:i` | `http://www.w3.org/2001/XMLSchema-instance` | Type attributes | |
| 35 | +| `xmlns:z` | `http://schemas.microsoft.com/2003/10/Serialization/` | Reference IDs (`z:Id`) | |
| 36 | +| `xmlns:a` | `http://schemas.microsoft.com/2003/10/Serialization/Arrays` | Arrays/collections | |
| 37 | +| `xmlns:b` | `http://schemas.datacontract.org/2004/07/ThreatModeling.KnowledgeBase` | Stencil properties | |
| 38 | +| `xmlns:c` | `http://www.w3.org/2001/XMLSchema` | Primitive type values | |
| 39 | + |
| 40 | +## File Structure (Correct Order) |
| 41 | + |
| 42 | +```xml |
| 43 | +<ThreatModel xmlns="..." xmlns:i="..."> |
| 44 | + <DrawingSurfaceList> |
| 45 | + <DrawingSurfaceModel z:Id="i1" xmlns:z="..."> |
| 46 | + <GenericTypeId xmlns="...Abstracts">DRAWINGSURFACE</GenericTypeId> |
| 47 | + <Guid xmlns="...Abstracts">{guid}</Guid> |
| 48 | + <Properties xmlns="...Abstracts" xmlns:a="...Arrays">...</Properties> |
| 49 | + <TypeId xmlns="...Abstracts">DRAWINGSURFACE</TypeId> |
| 50 | + <Borders xmlns:a="...Arrays"> |
| 51 | + <!-- Stencil elements (processes, data stores, external entities) --> |
| 52 | + </Borders> |
| 53 | + <Lines xmlns:a="...Arrays"> |
| 54 | + <!-- Data flow lines connecting stencils --> |
| 55 | + </Lines> |
| 56 | + <Notes xmlns:a="...Arrays"/> |
| 57 | + </DrawingSurfaceModel> |
| 58 | + </DrawingSurfaceList> |
| 59 | + <ThreatInstances> |
| 60 | + <!-- Threat entries --> |
| 61 | + </ThreatInstances> |
| 62 | + <ThreatMetaData> |
| 63 | + <!-- Metadata for threat categories and properties --> |
| 64 | + </ThreatMetaData> |
| 65 | +</ThreatModel> |
| 66 | +``` |
| 67 | + |
| 68 | +## Stencil Element Types |
| 69 | + |
| 70 | +Each stencil in `<Borders>` is wrapped in `<a:KeyValueOfguidanyType>`: |
| 71 | + |
| 72 | +```xml |
| 73 | +<a:KeyValueOfguidanyType> |
| 74 | + <a:Key>{guid}</a:Key> |
| 75 | + <a:Value z:Id="i2" i:type="StencilEllipse"> |
| 76 | + <GenericTypeId xmlns="...Abstracts">GE.P</GenericTypeId> |
| 77 | + <Guid xmlns="...Abstracts">{guid}</Guid> |
| 78 | + <Properties xmlns="...Abstracts"> |
| 79 | + <a:anyType i:type="b:HeaderDisplayAttribute" xmlns:b="...KnowledgeBase"> |
| 80 | + <b:DisplayName>Web Application</b:DisplayName> |
| 81 | + <b:Name/> |
| 82 | + <b:Value i:nil="true"/> |
| 83 | + </a:anyType> |
| 84 | + <a:anyType i:type="b:StringDisplayAttribute" xmlns:b="...KnowledgeBase"> |
| 85 | + <b:DisplayName>Name</b:DisplayName> |
| 86 | + <b:Name/> |
| 87 | + <b:Value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">My Component</b:Value> |
| 88 | + </a:anyType> |
| 89 | + <!-- Out Of Scope, Reason, Configurable Attributes --> |
| 90 | + </Properties> |
| 91 | + <TypeId xmlns="...Abstracts">SE.P.TMCore.WebApp</TypeId> |
| 92 | + <Height xmlns="...Abstracts">100</Height> |
| 93 | + <Left xmlns="...Abstracts">400</Left> |
| 94 | + <StrokeDashArray i:nil="true" xmlns="...Abstracts"/> |
| 95 | + <StrokeThickness xmlns="...Abstracts">1</StrokeThickness> |
| 96 | + <Top xmlns="...Abstracts">200</Top> |
| 97 | + <Width xmlns="...Abstracts">100</Width> |
| 98 | + </a:Value> |
| 99 | +</a:KeyValueOfguidanyType> |
| 100 | +``` |
| 101 | + |
| 102 | +### Stencil Shape Types |
| 103 | + |
| 104 | +| Shape | i:type | GenericTypeId | Description | |
| 105 | +|-------|--------|---------------|-------------| |
| 106 | +| Process (circle) | `StencilEllipse` | `GE.P` | Processes, web apps, services | |
| 107 | +| Data Store (parallel lines) | `StencilParallelLines` | `GE.DS` | Databases, storage, caches | |
| 108 | +| External Interactor (rectangle) | `StencilRectangle` | `GE.EI` | Users, external systems | |
| 109 | +| Trust Boundary | `BorderBoundary` | `GE.TB` | Trust boundaries | |
| 110 | + |
| 111 | +### Common TypeId Values (SDL TM Knowledge Base) |
| 112 | + |
| 113 | +| TypeId | Component | |
| 114 | +|--------|-----------| |
| 115 | +| `SE.P.TMCore.WebApp` | Web Application | |
| 116 | +| `SE.P.TMCore.AzureAppServiceWebApp` | Azure App Service Web App | |
| 117 | +| `SE.P.TMCore.AzureEventHub` | Azure Event Hub | |
| 118 | +| `SE.P.TMCore.DynamicsCRM` | Dynamics CRM | |
| 119 | +| `SE.DS.TMCore.SQL` | SQL Database | |
| 120 | +| `SE.DS.TMCore.AzureCosmosDB` | Azure Cosmos DB | |
| 121 | +| `SE.EI.TMCore.Browser` | Browser | |
| 122 | +| `SE.EI.TMCore.HumanUser` | Human User | |
| 123 | + |
| 124 | +## Data Flow Lines |
| 125 | + |
| 126 | +Lines in `<Lines>` also use `<a:KeyValueOfguidanyType>` with `i:type="Connector"`: |
| 127 | + |
| 128 | +```xml |
| 129 | +<a:KeyValueOfguidanyType> |
| 130 | + <a:Key>{line-guid}</a:Key> |
| 131 | + <a:Value z:Id="i10" i:type="Connector"> |
| 132 | + <GenericTypeId xmlns="...Abstracts">GE.DF</GenericTypeId> |
| 133 | + <Guid xmlns="...Abstracts">{line-guid}</Guid> |
| 134 | + <Properties xmlns="...Abstracts">...</Properties> |
| 135 | + <TypeId xmlns="...Abstracts">SE.DF.TMCore.GenericDataFlow</TypeId> |
| 136 | + <HandleX xmlns="...Abstracts">0</HandleX> |
| 137 | + <HandleY xmlns="...Abstracts">0</HandleY> |
| 138 | + <SourceGuid xmlns="...Abstracts">{source-stencil-guid}</SourceGuid> |
| 139 | + <SourceX xmlns="...Abstracts">0</SourceX> |
| 140 | + <SourceY xmlns="...Abstracts">0</SourceY> |
| 141 | + <TargetGuid xmlns="...Abstracts">{target-stencil-guid}</TargetGuid> |
| 142 | + <TargetX xmlns="...Abstracts">0</TargetX> |
| 143 | + <TargetY xmlns="...Abstracts">0</TargetY> |
| 144 | + </a:Value> |
| 145 | +</a:KeyValueOfguidanyType> |
| 146 | +``` |
| 147 | + |
| 148 | +## Property Attribute Types |
| 149 | + |
| 150 | +Properties use typed `<a:anyType>` elements: |
| 151 | + |
| 152 | +| i:type | Purpose | Has Value | |
| 153 | +|--------|---------|-----------| |
| 154 | +| `b:HeaderDisplayAttribute` | Section header | `i:nil="true"` | |
| 155 | +| `b:StringDisplayAttribute` | Text value (Name, Reason) | `i:type="c:string"` | |
| 156 | +| `b:BooleanDisplayAttribute` | Boolean (Out Of Scope) | `i:type="c:boolean"` | |
| 157 | +| `b:ListDisplayAttribute` | Dropdown list | Has `<b:SelectedIndex>` | |
| 158 | + |
| 159 | +## Threat Instances |
| 160 | + |
| 161 | +Threats go in `<ThreatInstances>` using `<KeyValueOfstringThreatpc_P0_PhBB>`: |
| 162 | + |
| 163 | +```xml |
| 164 | +<ThreatInstances> |
| 165 | + <KeyValueOfstringThreatpc_P0_PhBB xmlns:a="...Arrays"> |
| 166 | + <a:Key>{threat-guid}</a:Key> |
| 167 | + <a:Value> |
| 168 | + <ChangedBy/> |
| 169 | + <Id>{threat-guid}</Id> |
| 170 | + <Message>Description of the threat</Message> |
| 171 | + <ModifiedAt>2025-01-01T00:00:00</ModifiedAt> |
| 172 | + <Properties xmlns:b="...Arrays"> |
| 173 | + <b:KeyValueOfstringstring> |
| 174 | + <b:Key>Title</b:Key> |
| 175 | + <b:Value>Threat Title</b:Value> |
| 176 | + </b:KeyValueOfstringstring> |
| 177 | + <b:KeyValueOfstringstring> |
| 178 | + <b:Key>UserThreatCategory</b:Key> |
| 179 | + <b:Value>Spoofing</b:Value> |
| 180 | + </b:KeyValueOfstringstring> |
| 181 | + <b:KeyValueOfstringstring> |
| 182 | + <b:Key>StateInformation</b:Key> |
| 183 | + <b:Value>Not Started</b:Value> |
| 184 | + </b:KeyValueOfstringstring> |
| 185 | + <b:KeyValueOfstringstring> |
| 186 | + <b:Key>Priority</b:Key> |
| 187 | + <b:Value>High</b:Value> |
| 188 | + </b:KeyValueOfstringstring> |
| 189 | + <b:KeyValueOfstringstring> |
| 190 | + <b:Key>InteractionString</b:Key> |
| 191 | + <b:Value>Source → Target</b:Value> |
| 192 | + </b:KeyValueOfstringstring> |
| 193 | + </Properties> |
| 194 | + <SourceGuid>{source-stencil-guid}</SourceGuid> |
| 195 | + <State>AutoGenerated</State> |
| 196 | + <TargetGuid>{target-stencil-guid}</TargetGuid> |
| 197 | + </a:Value> |
| 198 | + </KeyValueOfstringThreatpc_P0_PhBB> |
| 199 | +</ThreatInstances> |
| 200 | +``` |
| 201 | + |
| 202 | +## Common Mistakes That Break TM7 Files |
| 203 | + |
| 204 | +1. **Adding `<?xml version="1.0"?>` declaration** — DataContractSerializer does NOT output this |
| 205 | +2. **Using `xmlns:xsi`/`xmlns:xsd`** instead of DataContract namespaces |
| 206 | +3. **Using simple XML element names** like `<Border>`, `<Line>`, `<Stencil>` — must use DataContract wrapper types like `<a:KeyValueOfguidanyType>` |
| 207 | +4. **Inventing custom elements** like `<MetaInformation>`, `<SecurityGaps>`, `<Mitigations>`, `<Assumptions>` — these DO NOT exist in the TM7 schema |
| 208 | +5. **Using human-readable GUIDs** like `users-browser` instead of proper UUIDs (e.g., `148ade68-5c80-40f3-8e1f-4e2cabdb5991`) |
| 209 | +6. **Missing `z:Id` reference attributes** on serialized objects |
| 210 | +7. **Missing the `xmlns` on child elements** — each `GenericTypeId`, `Guid`, `Properties`, `TypeId`, etc. must carry its own `xmlns="http://schemas.datacontract.org/2004/07/ThreatModeling.Model.Abstracts"` |
| 211 | +8. **Pretty-printing with indentation** — the correct format is a single continuous line of XML (no newlines or indentation within the content) |
| 212 | + |
| 213 | +## Reference |
| 214 | + |
| 215 | +Always use the `example-minimal.tm7` file in this skill's directory as a structural reference. Adapt the stencil types, names, properties, and data flows to match the user's architecture, but NEVER change the serialization format or namespace structure. |
0 commit comments