Threat Patterns User Guide
Threat Patterns finds threats in your model that no single element shows on its own. Each one appears only when several elements line up. For example, an agent may read content anyone can write, hold private data, and be able to send data where an outsider reads it. Each element can look acceptable alone, but together they form a path an attacker can use.
The analysis is deterministic. There is no AI, and a pattern finding carries no score. A finding is Confirmed or Not ruled out, and every part of it points back to something in your model. When the model does not say enough, the analysis tells you exactly what to add.
Who this guide is for
Security architects and analysts who model AI agents and their tools on the Dethernety platform, and the people who read the one-page sheet the analysis produces. You need to be able to open and edit your model.
Before you start
- A threat model with agents in it. The analysis looks at agents, their tools, MCP servers, harnesses, credentials and the flows between them.
- The Threat Patterns analysis and a pattern pack. Threat Patterns runs the pattern packs installed on your platform. The agentic pack provides the four patterns below. If you do not see Threat Patterns, or it says no pattern pack is installed, contact your administrator.
- Platform 0.11.0 or later for full results. This release adds the Origin and Credential fields on data items. On an older platform the analysis still runs, but those facts stay unanswered. The legs that depend on them stay undetermined and appear under Facts to establish. Nothing is confirmed on a fact the model does not state.
- Permission to run analyses on the model.
Run the analysis
- Open your threat model.
- On the canvas toolbar on the left, click the sparkles icon (tooltip Analyses). A dialog headed Analysis: model name opens, with the model's analyses.
- Click New Analysis and choose Threat Patterns from the menu. A row named Threat Patterns appears in the list.
- Click View results on that row. Before the first run, the page reads This analysis has not run yet.
- Click Generate. The analysis reads the model and the installed packs. When it finishes, the button reads Generate again, and you see the header and five tabs: Sheet, Findings, Fixes, By item and Facts to establish. The page opens on Sheet, unless you followed a link to another tab. The Facts to establish label carries the number of questions it asks, for example Facts to establish (4).
If you change the model later, a banner reads The model changed since this run. Generate again to read the current model. Click Generate again to refresh. Nothing changes until you do. Moving or resizing elements on the canvas, or changing which side a flow leaves from, does not mark the result out of date.
The banner also shows after Threat Patterns or its credit table is updated: a result's fingerprint includes the model, the version of Threat Patterns that made it and its credit table, so a change in any of them marks the result out of date. After an engine update it reads Threat Patterns was updated (engine old version → new version) since this run. Generate again to read the current model. It names the update alone, even if you also changed the model, because a new engine can read the model differently. After an update of the credit table alone it reads Threat Patterns was updated since this run. Generate again to read the current model. When you changed the model and the credit table was updated, the banner names both, the model first.
The banner reads The model or Threat Patterns changed since this run. Generate again to read the current model. when it cannot tell which changed: the result was generated before Threat Patterns engine 0.1.5, the server does not report what changed, or only your assertions changed. After you update to engine 0.1.5, every earlier result shows this banner once, until you generate it again. A model update that changes nothing, for example saving the same answers again, does not mark a result out of date.
The same banner shows when:
- You assert or withdraw an assertion on this analysis. It shows at once, without a reload. See Act on a question.
- An exposure's disposition changes. When you change it from the analysis, with Affirm or Disposition…, the banner shows at once. A change made elsewhere on the platform shows the next time you open the analysis. See Dispositions on exposures.
A pattern pack the engine did not run. A pattern pack can need a newer Threat Patterns engine than the one installed. The engine then skips that pack and runs the others. A notice above the tabs names each pack it skipped:
Pattern pack pack@version needs the Threat Patterns engine version or later; the engine is version. Upgrade the engine module. It was not run.
The report holds no findings from that pack. Ask your administrator to upgrade the Threat Patterns engine module, then click Generate again. The exported sheet carries the same line under its title.
Read the header
The header reads Threat Patterns · model name. Under it are the generated time, for example "Generated 11 Oct 2026, 20:58 UTC", and two count lines:
- Systemic findings, by confidence: "5 systemic findings: 2 Confirmed · 3 Not ruled out".
- Element exposures, by whether a finding holds them and by triage: "29 element exposures: 14 not inside a finding · 9 inside one · 6 accepted or dismissed, not counted · 20 untriaged".
Accepted and dismissed exposures (triage accepted or dispositioned) are listed, but never counted. The two lines are never added together.
The four patterns
| Pattern | What it means | Parts (legs) that must line up | Makes it worse |
|---|---|---|---|
| Lethal trifecta (critical) | Untrusted content can steer the agent into sending private data where the attacker reads it | U untrusted content reaches the agent · P the agent can read private data · X the agent can transmit to where an outsider reads | W the agent writes without approval |
| Credential chain (critical) | A foothold in the agent stack reaches a credential that unlocks sensitive data or privileged actions | foothold · reach the credential · unlock something with it | weak credential |
| Injection to action (high) | Untrusted content can trigger a write, destructive or code-execution action that nobody approves | untrusted input · action tools · no gate (no approval) | sensitive target · broad identity |
| Delegation hop (high) | Untrusted content reaches an agent that hands the work, with its origin, to an agent holding the other legs | untrusted content at the delegator · origin carried to the delegate · delegate holds the rest | open delegation |
Read a finding
A finding appears when at least two required legs are present and none is absent.
- Confirmed: every required leg is present.
- Not ruled out: N present, M undetermined: some legs are present, and the model does not say enough to decide the rest. This is not a lower grade of risk. It means the model is missing a fact.
Each leg is present, absent or undetermined. Expand a finding to see each leg's routes: the elements and flows that make it present, with a label that says where the evidence comes from:
| Label | Meaning |
|---|---|
| stated | Something you drew or answered, used directly |
| derived from topology | Inferred from what you drew, for example content carried out of an untrusted zone |
| class premise | Follows from the element's class, for example an Untrusted Content Source |
| class exposure | An exposure the element's class raised |
| from class list | The data item's class is a known credential class |
| from host mode | Read from the approval mode of the harness that runs the agent |
| via executor / via neighbour | The agent transmits through a tool executor or a neighbouring element |
| analyst assertion | An assertion you recorded on this analysis |
| affirmed | An exposure the class raised and someone affirmed on the platform. The route still counts, and names the affirmation and its time |
| dispositioned | An exposure left out by its disposition (false positive, not applicable or superseded). The route reads absent and names the exposure. See Dispositions on exposures |
Where the evidence names a zone, it reads as the model editor names it: the word on the zone's pill in the diagram, then the zone's Trust zone name, for example "Customer (Untrusted, Open internet)" or "CRM (Vendor, Trusted external)".
An undetermined route has no label. It shows to settle: and names the fact or drawing that would decide it, and on which element.
Controls. A control counts against a leg only when its countermeasure is linked to a technique that route stands for. The link is either the countermeasure's own edge to the technique, or a MITRE mitigation of the technique, which the analysis's credit table classes as prevention or detection from the mitigation's own MITRE description. A mitigation the credit table does not hold credits detection. A finding then reads control modelled. A control that only detects reads detected only. Detection never counts as prevention. Otherwise the finding is unmitigated. A credited finding names the required legs that earn its word, for example "detected only on U". The leg dialog shows how each credit was earned; see Dialogs.
A finding leaves that state in one of two ways. Set the elements' attributes so that a required leg is absent, and the finding disappears on the next run. Or model a compensating control whose countermeasure credits a required leg's technique, and the finding then reads control modelled, or detected only for a detection. Either way, click Generate again to see the change. Nothing marks a finding as done by hand. On the Findings tab and in the sheet's top findings, hover over or move to the word unmitigated to see these two ways again.
Element exposures. Your element classes also raise exposures of their own. Each one shows a triage, taken from its disposition on the platform:
| Triage | Platform disposition |
|---|---|
| untriaged | none yet |
| analyst-confirmed | Affirmed |
| accepted | Risk Accepted |
| compensate | Compensating Control |
| dispositioned | Not Applicable, False Positive or Superseded. Counted apart |
Beside the triage, an exposure can carry a control note, control modelled or detected only, by the same rule as above. The note stays whatever the triage, for example "untriaged · control modelled". A control can also sit on a data item. It then counts for the exposures on that data item, and for a finding's route on it. It does not count for the element that handles the data item, and a control on that element does not count for the data item, unless that element is one of the finding's own agents: a control on one of them, or on a boundary around it, counts for every route of that finding. With the agentic pack, no required leg has a route on a data item, so a control on a data item changes the notes on that data item's exposures and no finding. analyst-confirmed is an analyst's verdict on one exposure. It is not a pattern's Confirmed.
An analyst-confirmed, accepted or compensate exposure still counts in systemic findings: accepting or compensating a risk changes no fact in the model. A dispositioned exposure is left out of the analysis, and so are the routes of a finding that rested on it. See Dispositions on exposures.
An element exposure can sit inside a systemic finding: it is on an element that supplies one of the finding's legs, and it shares a technique family with the pattern. Findings shows where it appears.
Where several exposures are counted by triage, the total comes last: "3 analyst-confirmed · 2 accepted · 24 untriaged, 29 in all". A single state stands alone: "15 untriaged". Dispositioned exposures are added as "; 4 dispositioned, counted apart".
Findings
The Findings tab lists systemic findings and element exposures. You can filter by Scope, Severity, Confidence, State and Zone. State offers both the finding states and the triage states. Zone names each zone as the model editor does, for example Untrusted (Open internet) or Vendor (Trusted external). A line above the list says how many rows are shown, for example "12 of 41 shown".
Group and rank
Group by defaults to Pattern: one group per pattern, then Element exposures. The other groupings are Scope, Subject, Severity and State. Click a group's header to fold or unfold it. With the keyboard, move to the ▸ or ▾ at its start with Tab and press Enter or Space. A group with more than 25 rows starts folded.
Findings are ranked by one rule in every grouping. It is stated once above the list:
Ranked Confirmed before Not ruled out, then the pattern's severity band, then unmitigated or detected only before a control modelled, then more aggravating legs present.
Pattern groups
A pattern group's header shows the severity band, the pattern and its counts, for example "3 findings: 1 Confirmed · 2 Not ruled out". The line under it gives the pattern's reason, followed by "Severity is the pattern's band."
The pattern's legs are named columns, required legs first. Aggravating legs are muted. Each finding row has one mark per leg:
| Mark | Leg state |
|---|---|
| ● | present |
| ◐ | undetermined |
| ○ | absent |
In the other groupings, the same marks sit in the row, each beside its leg's name.
Finding rows
- Band. The severity band stands alone. A Not ruled out finding has if confirmed on a line under it.
- State. For example "Confirmed · unmitigated" or "Not ruled out · control modelled on P". A control modelled or detected only finding names its credited required legs after on. Amber marks only what is still open. A Not ruled out finding's state is amber, with a link N questions → that opens its questions on Facts to establish. Where another element's legs decide the finding, the link reads what decides it →.
- Exposures inside. A finding with element exposures inside it shows N exposures inside.
Element exposure rows
An exposure row shows its triage and control note. Untriaged exposures are muted. An exposure inside a finding shows one inside: chip that names the finding, and +N when it sits inside more than one. Click the chip to open that finding's dialog. See Dialogs.
Exposures inside a finding are hidden from the list by default. Click show the N element exposures inside a finding to list them too. The toggle names the accepted or dismissed ones apart, so its count matches the header: "show the 19 element exposures inside a finding (1 accepted or dismissed)" while the header says "18 inside one".
Tooltips
Hover over a part of a finding to see what it means:
| Part | The tooltip shows |
|---|---|
| Pattern name (grouped by Pattern only) | The pattern and its band, its reason, then Required legs and Aggravating, never counted, each leg with what it means |
| Leg column header | The leg, what it means, and what its role means. Required: every required leg must be present for a Confirmed finding. Aggravating: makes the finding worse, but never counts toward it |
| Mark in a row | The leg, its mark and state, what the leg means, what the state means, and the role; when a control credits the leg, also its credit and what it means. In the groupings other than Pattern it also gives the evidence label, where there is one |
| unmitigated, control modelled or detected only in a finding's state | The word, with the credited legs it names, and what it means. For unmitigated, the two ways out: attributes that make a required leg absent, or a compensating control whose countermeasure credits a required leg's technique. Then Generate again |
Pattern names, leg headers and these state words have a dotted underline. Move to them with Tab to open the tooltip, and press Escape to close it. The marks in a row open on hover only. Each row's screen-reader text already names every leg and its state.
The sheet's top findings carry the pattern and coverage tooltips too. See The sheet.
Expand a finding
Click a row to expand it, and click it again to close it. With the keyboard, move to the row's title with Tab and press Enter or Space. The ▸ before the title turns to ▾ while the row is open. Clicking the element name opens the element instead.
An expanded finding reads in this order:
- The pattern's reason, then the confidence (for example Not ruled out: 2 present, 1 undetermined), the coverage, and the pattern with its version.
- The finding's diagram. See Read the diagram.
- For a credential chain, its Paths: foothold → reach → unlock.
- Each leg with its routes and their labels. Every undetermined route has a to settle: line with its next step, such as Answer it. An attribute it names reads by its title in the model editor, as on Facts to establish. Where elements in the finding's to settle: lines share a name, they read "name (from A to B)" for a flow and "name (in parent)" for another element, as on Facts to establish.
- Fixes.
- The element exposures inside, each with its triage and control note. Accepted or dismissed ones are collapsed behind show N accepted or dismissed.
- Dispositions, when the finding rests on a dispositioned exposure or left one out: each exposure, who set its disposition and when, and whether the finding still counts it. See Where a disposition shows.
The next step is Answer it, Draw it or Ask the owner, by what the question asks. See Act on a question.
+ Issue beside the pattern's reason, and beside each fix, turns the finding or the fix into a tracked issue. See Raise an issue.
+ Risk beside the pattern's reason records the finding as a risk in Risk Assessment's register, or adds it to one. See Record a finding or an exposure as a risk.
Expanding an element exposure lists its techniques by id and name, then the score the exposure's policy gave it ("score none" when it has none) and its disposition in words, for example "disposition false positive · left out of the analysis". See Where a disposition shows. Click a technique to open its dialog. A name appears once it has been read from the platform. Click Open the exposure to open the exposure's dialog. See Dialogs.
Read the diagram
The diagram draws the finding as a fishbone. The line above it reads "every required leg must be present".
- Head. The box on the right is the finding: its title, the element it is at, Confirmed or Not ruled out, and the severity.
- Bones. One bone per leg. Its label gives the leg and its state, for example "foothold · present", and control modelled or detected only when a control in the model credits the leg. Required legs sit nearest the head. Aggravating legs sit left of a short tick on the spine, drawn as a thin double bone, and the line above adds that they never count.
- Ribs. Each route is a rib off its leg, with the route's kind and, where it has one, its element. A leg shows up to four routes, then +N more routes.
- Small bones. Under a route, in this order: the control note and the control that credits it, for example "detected only · control" (+N for more controls), the questions that would settle it (amber, starting "?"), the evidence label, and how many exposures it carries. A route shows up to three, then +N more.
- State. A present leg or route is drawn solid, an undetermined one dashed amber, an absent one faded. Colour never carries the state alone: each leg's state is written in its label, and each route's in the leg's details.
Click any part, or move to it with Tab and press Enter or Space. Each part opens a dialog; see Dialogs. The head opens the finding in full. A leg, route or small bone opens the leg dialog; see Dialogs. An element name opens the element's profile. A question opens its next step, Answer it, Draw it or Ask the owner. The diagram keeps a question's short text; the dialogs give the attribute's title. From the leg, an exposure opens with its description.
Show where a fix cuts: above the diagram lists the fixes that break or downgrade the finding. A partial fix is not listed: it narrows its routes and cuts none. Click one to draw a cut mark on the bone it breaks; click it again to remove it. A fix that cuts more than one kind of route on a leg draws the cut on the rib of each of them. A link from the Fixes tab opens the finding with its change already selected.
The Sheet tab shows the same diagram under each top finding, and the exported sheet carries it as a static picture.
Fixes on a finding
Each fix names the change, the element it lands on and its owner. It says what the fix does to this finding: breaks this finding alone, downgrades it to Not ruled out, clears it: no longer raised once set, or does not break it alone. A fix counts as breaking a finding only when a required leg becomes absent once the fix is applied.
Who holds a fix. Who can make a change depends on two things: who runs the element it lands on, and what the change touches. A change can touch a setting the element offers you, the element's own software, or the environment the element runs in. A setting is always yours. The element's own software belongs to whoever runs the element. The environment belongs to whoever runs the boundary the element is drawn in, when that boundary says so; otherwise to whoever runs the element. So a fix is one of three kinds:
| Kind | Chip beside the owner | The owner reads | What it means |
|---|---|---|---|
| Change | none | A role, such as "operator of the agent". On an element a vendor runs: "you, through the settings the vendor offers for element: settings" | You can make it, and it does what its line says |
| Partial | partial: narrows, does not close | "you, in part, through the settings the vendor offers for element: settings" | You set it through what the vendor offers, but it only narrows the routes. On its own it does not break, downgrade or clear the finding |
| The vendor's | compensate or accept | "the vendor of element (product)", or "the vendor running boundary (product)" | Only the vendor can make it. Compensate where you hold a lever, or accept the risk |
The product shows only where the model records one. A fix whose elements read differently, for example one you run and one you set through a vendor's settings, shows both owner phrases joined by "; ". When you run the boundary a vendor's element is drawn in, a change to its environment is yours, and the owner ends "you run boundary".
A partial fix reads "narrows, does not close; if it cut those routes it would break this finding" (or downgrade it, or clear it). That is what it would do if it closed the routes. It does not close them. Under it, what stays open: names what remains, for example "what the signed-in user can reach stays readable to it". It may also carry a question to put to the vendor.
A fix the vendor holds names the vendor. Under it you may see:
- a question to put to the vendor, for example "Ask the vendor how the agent's outbound requests are restricted";
- compensate where you hold a lever: and the finding's fixes on its other legs that are yours, with their legs. These are the changes you can make on this finding while this one stays with the vendor.
who holds it depends on: A fix can carry this amber line when the model does not say who runs an element, and the answer could change who holds the fix. Click Answer it and answer Operated by on the element it names; see Answer who runs an element. The question takes one of these forms:
- "who builds or runs element's own software? Answer Operated by, under Operation & version in its class attributes"
- "element sits in boundary, run by the vendor: who runs element itself? Answer Operated by, under Operation & version"
- "who runs the environment of what is drawn in boundary? Answer Operated by, under Operation"
- "classify element, then answer who runs it", or "classify boundary, then answer who runs its environment", when it has no class yet
A fix on a setting never asks: a setting is yours whoever runs the element. These questions show on the fix, not on Facts to establish.
When no single change settles a leg, a line names the changes that settle it together, and says whether together they break the finding. A partial part ends narrows, does not close, and a combination with one does not break the finding: its line reads "leg, all together (does not break it: a lever only narrows its route):". When the combination falls short for another reason, it reads "does not break it: another route stays undetermined". When one of the routes can only be closed by the vendor, there is no combination. The route is named instead: "leg route (element): its only fix is the vendor's: compensate or accept (vendor)".
Answer who runs an element
Who runs an element comes from its Operated by field. It sits in the last panel of the element's Attributes tab: Operation & version on a component, Operation on a boundary. The panel shows once the element has a class. Choose You (your organisation) or A vendor.
- On a component, it says who builds or runs the element's own software. Choose A vendor for a hosted service you only configure. Choose You (your organisation) for something you build or run, also on a vendor's platform.
- On a boundary, it says who runs the environment of what is drawn directly in it: the hosts or the platform runtime. Draw each element directly in the boundary that runs its environment. The canvas itself never speaks for an environment.
- Product names the vendor and product. A fix the vendor holds shows it after the vendor.
Leave it empty unless you know. Do not guess. An empty field is read from the zone instead: an element in a Vendor (Trusted external) zone counts as the vendor's, any other as yours. Each fix whose holder depends on it then asks, so the open answer stays visible. A guess would hide it, and the fix would rest on it. A value other than the two choices, for example from an imported model, counts as yours, and the fixes ask about it too.
A flow has no field of its own. It counts as the vendor's only when every element it connects is. A data item is always yours.
Click Generate again after you answer. The fixes then follow your answers. The full guidance on the panel is in Operation & version.
Dialogs
A finding, a leg, an element exposure, an element, a MITRE technique, a part of an exposure's map and a question's next step (Answer it, Draw it or Ask the owner) open as dialogs over the tab you are on. You open them from the diagram, an inside: chip, an element name, an exposure inside a finding, Open the exposure on an expanded exposure row, a technique id, an exposure's map, or a link on By item.
Dialogs stack. A dialog opened from another opens over it: a finding, then an exposure inside it, then the exposure's element, or a leg, then Answer it. The dialog on top offers Back to and the name of the dialog under it. A long name ends in an ellipsis; hover over the button to read it in full. Click it, press Escape or click outside the dialog to go back one. Close closes them all. If you open something that is already open lower down, you go back to it. It does not open twice.
The finding dialog shows the finding in full. It opens from the diagram's head, an inside: chip, a link on By item, or an exposure's Part of. Under The pattern it says what each leg means, required legs first, then the aggravating ones. Under This finding it shows what the expanded row on Findings shows: see Expand a finding. That includes the diagram with Show where a fix cuts:, and the next step on each to settle: line. In this dialog the diagram's head opens nothing.
The leg dialog opens from a leg, route or small bone on the diagram. Under the title, it says why the leg is present, undetermined or absent. What this means gives the leg's letter and name, what the leg means, what its state means, what its credit means when a control credits it, and what its role means. These are the same words as a leg mark's tooltip on Findings. Routes then lists each route with its evidence, the controls that credit it, its exposures and its questions, each attribute by its title and each question with its next step. The fixes that act on the leg come last.
Each credit reads "credited by control · prevention · technique", or detection, then says how it was earned (see Controls in Read a finding):
- Through an edge, named by the platform's relation, for example: through its countermeasure's DETECTS edge, which reads as detection.
- Through a mitigation, for example: through mitigation M1050 Exploit Protection, which the credit table classes as prevention. The next line quotes the mitigation's MITRE description: MITRE: "…".
- Through a mitigation the table does not hold: through mitigation id, which the credit table does not hold, so it credits detection.
Click the technique in a credit to open its dialog.
The exposure dialog shows what the platform holds about the exposure. Beside the element's name under the title are + Risk, + Issue, Affirm and Disposition…; see Affirm or disposition an exposure. Under them, beside the exposure's state, a chip gives its disposition in words; see Where a disposition shows. Under Techniques, each technique shows its id and name, which open the technique's dialog, its framework, the technique it is part of, its tactics, the first lines of its description and its MITRE mitigations. The dialog does not list the countermeasures of those MITRE mitigations. Mitigation suggestions, Detection methods and References follow, each only when the exposure has some. Under Part of it lists the findings the exposure sits inside. Click one to open that finding's dialog.
Why the platform raises it shows the rule behind the exposure, from the platform's knowledge graph, and how it reads this element. It explains why the rule raises the exposure; it is not a verdict on the element.
- The map. For each threat behind the rule, a map is drawn from top to bottom: the attributes the rule reads, the rule, the threat, and the sources the threat cites. With no threat recorded, the map shows the rule alone. The attributes of a condition group that holds on the element are drawn bold as the cause; the rest are the rule's other inputs, as a legend line says. The threat's techniques sit in a dashed chip beside the rule, marked provisional · Dethernety synthesis: the mapping is the knowledge graph's, not MITRE's. Many techniques wrap into rows inside the chip. A map is drawn only when one of the rule's condition groups holds on the element.
- Open a part of the map. Click an attribute, the rule, a threat or a source to open its dialog over the exposure's. Click a technique id in the map to open the technique's dialog.
- The text under the map. The rule's name, then what the rule says, then It reads: and the attributes it reads. Each condition group follows in words, with its verdict and the element's own values, for example "Group 1 holds on this element:
egresseqopen(here: egress = open)". The attribute and operator read as the rule states them; an attribute the element has no value for reads "attribute: value not recorded". A verdict is holds on this element, does not hold or cannot be decided from the recorded values. The rule raises the exposure when any one group holds, and a group holds when every condition in it does. Each threat behind the rule follows with its attack surface, its techniques, each opening its dialog, and its sources. - With the keyboard. The map is one picture; a screen reader reads the chain in words. The rule's name, each attribute after It reads: and each threat's name in the text are buttons that open the same dialogs as the map.
When the knowledge graph is not installed or could not be reached, the platform's knowledge-graph access does not include this request, the platform's knowledge-graph version does not include the element's class, it has no rule of this name for the element's class, the element is not an instance of a class, the exposure was added by hand, or the rule could not be read from the platform, one line says so instead, and no map is drawn. After Generate again, the dialog reads the reasoning afresh, so it shows the element's values as they are now.
A dialog from the map shows one part of it:
| Part | The dialog shows |
|---|---|
| An attribute | Its title and description as the rule reads it, the element's value or no value recorded, and the condition groups that read it, each with its verdict |
| The rule | What the rule says, and every condition group with its verdict and the element's values |
| A threat | Its attack surface, description, techniques (each opening the technique's dialog) and sources |
| A source | Its link, noted as opening outside the product. A source with no web address shows its text instead |
The element dialog opens from an element name anywhere and shows the element's profile. A crown jewel reads ★ crown jewel in the title. Zones read as the model editor names them, for example "zone Public (Internet-facing)". Under the title, a line names the element's class and the module that provides it: "class · module version". An element that is not an instance of a class reads No class: the element is not an instance of a class. Under the element's description, About the class gives the class's description, when it has one. If the platform cannot be read, the class line and About the class are left out. Beside the profile, a small map of the model shows the element highlighted: a data flow with both its ends, a boundary, or for a data item the elements that handle it. Crown jewels carry a star. The line under the map says what is highlighted, and the expand button opens the map larger. Under In this analysis the dialog lists the systemic findings at the element (here), then those with a route through it (through here), each with its state, then the element's exposures, each with its severity as a coloured chip: critical, high, medium or low, in the same colours as in Risk Assessment. An exposure with a disposition also carries its disposition chip. Each exposure row ends with + Risk, + Issue, Affirm and Disposition…. Click an exposure to open its dialog over the profile. When the model cannot be read, the profile says so, and the descriptions and In this analysis still show.
The technique dialog opens from a technique id: under Techniques or Why the platform raises it in an exposure dialog (its map included), in a threat's dialog from the map, on an expanded exposure row on Findings, or in a leg dialog's credit. Above the title it reads ATT&CK technique or ATLAS technique, and the title is "id · name". Under the title are its tactics and the technique it is part of. Click that technique to open its dialog over this one. Then come the technique's description and its MITRE mitigations, and the link Open id on attack.mitre.org (or atlas.mitre.org). The last line reads: "The name, description, tactics and mitigations are MITRE's. That this technique belongs to the exposure or leg it was opened from is the class's or the pattern pack's mapping, not MITRE's." When the platform cannot supply the technique, the dialog reads No description is available for this technique here. and still shows the id and its link. An id that is not a well-formed ATT&CK or ATLAS technique id stays plain text and opens nothing.
Open in Findings. A finding, leg or exposure dialog has Open in Findings. It closes all dialogs and opens the row on the Findings tab, expanded and scrolled into view. For a leg, that is its finding's row. Filters are cleared only when they hide the row.
Fixes
The Fixes tab ranks the changes across the whole model. Changes are grouped by what they change, who owns it and their kind, strongest first: findings broken, then Confirmed findings downgraded to Not ruled out, then findings cleared. Partial fixes come after every change. See Fixes on a finding for the kinds.
- A group shows the change, its owner and the elements it lands on. It counts every finding any of its elements breaks, each once, out of the total, for example "breaks 3 of 7 findings; downgrades 1 of 7 to Not ruled out".
- Elements. Under the group's header, a line names three elements, then and N more. Click it to show them all; it then reads show fewer. A group on a single element names it.
- Click a group to see its elements. Each element has its effect line, for example "breaks 1 of 27 findings:", and under it the findings the change reaches there. Each finding is a link that reads "finding at element". Where the change reaches that element's findings in more than one way, each link names its effect: "breaks", "downgrades to Not ruled out" or "clears".
- or instead: A group whose broken findings are all broken by a stronger group shows under that group. It reads "breaks the same N" when it breaks the same findings, or "breaks K of those" when it breaks fewer. A change that breaks nothing (it only downgrades or clears) always stands alone. Click an alternative to open it the same way as a group.
- Partial fixes carry the chip partial: narrows, does not close beside the owner. Their line reads "narrows, does not close; if it cut those routes it would: breaks 2 of 7 findings", ranked by what they would do. Their links read "would break if it cut", "would downgrade if it cut" or "would clear if it cut". A partial fix always stands alone, never as an alternative to a change.
Click a finding link to open the finding on the Findings tab, expanded and scrolled into view. When the change breaks or downgrades the finding, its diagram opens with that change selected under Show where a fix cuts: and drawn where it cuts. A finding the change only clears, or a partial fix narrows, opens with no change selected. Neither is drawn as a cut.
The address keeps the finding and its change while you stay on Findings, so a reload or a shared address opens them again. If the change no longer applies to that finding, for example after you generate again, the finding opens with no change selected. Switching tabs clears the address, so coming back to Findings opens nothing.
A fix the vendor holds reads compensate or accept. It is not ranked on this tab; it shows on its finding, with the vendor named. The footer says so: "A fix the vendor holds is compensate or accept, not ranked here; it shows on its finding. A partial fix only narrows its routes: it is listed after the changes, by what it would do if it cut them."
A finding link also carries + Issue when the finding lists the change as one of its own fixes. It raises an issue for that fix. See Raise an issue.
Raise an issue
Turn a finding, a fix or an exposure into a tracked issue, so the work it calls for gets an owner. The issue is a platform issue like any other: you edit, assign and close it on the issue board. Raising an issue does not change the finding. Only a change to the model, then Generate again, does that.
Where to find + Issue:
- A systemic finding: beside the pattern's reason, at the top of an expanded row on Findings and in the finding dialog.
- A fix: beside each fix under Fixes in an expanded finding or the finding dialog, and beside a finding link under a change on the Fixes tab.
- An element exposure: beside each exposure under In this analysis in the element dialog, and beside the element's name under the title of the exposure dialog.
To raise an issue:
- Click + Issue. The platform's Raise an issue from this finding dialog opens, with the name of what you raise it from.
- Choose one:
- Add to Issue board copies the issue to the issue board and takes you there.
- An issue class under Or create an issue: creates the issue now and opens it for you to edit.
- If you created an issue, close it when you are done editing.
A message at the bottom of the analysis reports the outcome: Issue created. or Copied to the issue board. If you click Cancel, nothing is raised and no message shows.
Where the issue lands. The issue is attached to one element of the model:
| You raise it from | The issue is attached to |
|---|---|
| A finding | The element the finding is at |
| A fix | The element the fix lands on, when it lands on exactly one. Otherwise the element its finding is at |
| An element exposure | The exposure's element |
When there is no such element, the issue is attached to the model itself.
What the issue says. Its name is the finding's title, the fix's change or the exposure's name, followed by "Issue on element". The description depends on what you raise it from:
- A finding carries a plain-text summary that starts "Threat Patterns finding:". It names the finding and the element it is at, Confirmed or Not ruled out, the severity, and each leg's state. It ends with the first fix that breaks or downgrades the finding: the change, its owner, where it lands and what it does.
- A fix carries a summary that starts "Threat Patterns fix:". It gives the fix first, then the finding it acts on.
- An element exposure carries the platform's own description, "Exposure:" and the exposure's name.
A summary is at most 400 characters. A longer one is cut short with an ellipsis.
If + Issue is greyed out, hover over it. Unavailable — the host platform is too old for issue actions means your platform does not offer issues to Threat Patterns yet. Ask your administrator to upgrade it. When it is available, the tooltip reads Create or link a tracked issue.
Record a finding or an exposure as a risk
Record a systemic finding or an element exposure in Risk Assessment's risk register, so the risk behind it gets an assessment, an owner and a treatment decision. You do not need to open a Risk Assessment analysis for this. The risk lives in the register like any other risk: you rate it, decide its treatment, accept it and close it there. See The Risk Register. Recording a risk does not change the finding or the exposure. Only a change to the model, then Generate again, does that.
You need Risk Assessment on your platform. Without it, + Risk is greyed out, and its tooltip says why; see Troubleshooting.
Where to find + Risk
+ Risk always sits just before + Issue:
- A systemic finding: beside the pattern's reason, at the top of an expanded row on Findings and in the finding dialog.
- An element exposure: beside each exposure under In this analysis in the element dialog, and beside the element's name under the title of the exposure dialog. An expanded exposure row on Findings has no + Risk. Click Open the exposure to reach its dialog.
Fixes have no + Risk.
Beside + Risk, a chip names each risk the finding or exposure already feeds: its reference handle, status and treatment, for example "DT-CS-260717-4 · open · undecided". The chips are read only. To change a risk, open it in the register.
An exposure's chip ends in · dispositioned, in amber, when the exposure has a disposition on the platform other than Affirmed: Risk Accepted, Compensating Control, Not Applicable, False Positive or Superseded. The platform then no longer counts the exposure as live. The risk is unchanged; open it in the register and decide whether it still stands. The marks are read again each time the register is read, and after Generate again. This mark is wider than the triage dispositioned under Element exposures in Read a finding: it covers accepted and compensate too.
Record a new risk
- Click + Risk. A dialog opens, headed Risk register and the finding at its element, or the exposure on its element.
- Keep Record as risk… selected.
- Check the three parts of the risk statement. Each is filled in from what you clicked, and you can edit it. See What the risk statement starts with.
Each part holds at most 400 characters. A longer text is cut short with an ellipsis. Record risk stays greyed out while a part is empty. - Optional: choose a Likelihood (Rare, Possible, Likely, Almost certain) and an Impact rating (Low, Medium, High, Critical), and enter an Owner. The two ratings start at Not assessed.
- Click Record risk. The dialog closes, and a message at the bottom of the analysis reads Risk recorded. A chip for the new risk appears beside + Risk.
The treatment starts as Undecided. Decide it, and accept the risk, in Risk Assessment's register.
What the risk statement starts with
For a systemic finding:
- Cause: what each present leg means, then the legs not yet determined, by name.
- Event: the finding at its element, with Confirmed or Not ruled out.
- Impact: the reason for the finding's severity.
For an element exposure:
- Cause: the rule that raises the exposure, from the platform's knowledge graph, and what the rule says. Until the rule is read, or when there is no rule, it says only what is known: "A person added this exposure to element by hand." for an exposure a person added, "It is on element, which is not an instance of a class." when the element has no class, and otherwise "The platform raises this exposure on element."
- Event: "exposure on element (Threat Patterns element exposure, severity severity)."
- Impact: the threats behind the rule, as "Threats: …". When the exposure sits inside a finding that a fix on the exposure's element breaks or downgrades, the fix follows, as "Fix, for the finding "finding": change (owner, what it does to the finding)." With neither, it reads "Severity severity."
The rule and its threats arrive a moment after the dialog opens, once they are read. They fill Cause and Impact only where you have not edited the text yet. Your own words stay.
Add the finding or exposure to a risk
- Click + Risk.
- Select Add to risk….
- Under Risk, choose a risk. The list holds the open risks this finding or exposure does not feed yet, each by its reference handle and event. When there is none, Add to risk… is greyed out.
- Click Add evidence. The finding or exposure is added to the risk as evidence. The risk's own words stay as they are. The dialog closes, and the message reads Evidence added.
If someone deleted the risk in the meantime, the message reads That risk is no longer in the register. Nothing is saved, and the list is read again. Choose another risk, or record a new one.
If a save fails for any other reason, the message reads Couldn't save the risk. Nothing is saved, and the dialog stays open so you can try again. Click Cancel to close the dialog without saving.
What the register keeps
Either way, the finding or exposure is linked to the risk as evidence.
For a systemic finding, the evidence holds:
- the finding's title at its element, Confirmed or Not ruled out, its severity and the reason for it
- the finding's severity and a digest of the finding, both read from Threat Patterns when you save. They let the register tell you later when the finding has changed since you linked it
- the analysis the finding came from
- links to the element the finding is at (a component or a data item) and to the model. When that element has been deleted from the model since the run, the evidence is linked to the model alone
Threat Patterns reads the finding as it stands before it saves. If it cannot, the message reads Couldn't confirm it still stands as shown, so nothing was saved.
For an element exposure, the evidence holds:
- the exposure's name, and "exposure on element". When a person added the exposure by hand rather than the platform raising it, the text ends ", added by hand". Threat Patterns reads who added it from the platform. When it cannot tell, the text makes no claim either way
- the exposure's severity and a digest of the exposure, both read from the platform when you save. They let the register tell you later when the exposure has changed or gone since you linked it
- the analysis you recorded it from
- links to the exposure's element (a component, data item, boundary or data flow) and to the model
Threat Patterns saves an exposure only while the platform still holds it on its element as it is. If the exposure is gone, for example because a change to the element removed it, or it cannot be read, nothing is saved and the message reads Couldn't confirm it still stands as shown, so nothing was saved. Click Generate again to see the exposures as they are now.
When + Risk is greyed out
Hover over + Risk to see why. When it is available, the tooltip reads Record this finding as a risk, or add it to one, or on an exposure Record this exposure as a risk, or add it to one.
| Tooltip | Meaning |
|---|---|
| Unavailable — the risk register comes with Risk Assessment | Risk Assessment is not installed on your platform |
| Unavailable — this platform's Risk Assessment does not take Threat Patterns findings yet | Your Risk Assessment is too old to take Threat Patterns findings. Threat Patterns learns this from the first save it refuses: the same words show as a message and nothing is saved. Click Cancel to close the dialog. + Risk on findings then stays greyed out until you open the analysis again |
| Unavailable — this platform's Risk Assessment does not take Threat Patterns exposures yet | The same for exposures. Your Risk Assessment may take findings but not yet exposures, so each is learned on its own: + Risk on findings stays available |
In both cases, ask your administrator.
Dispositions on exposures
A disposition is the platform's verdict on one element exposure: affirmed, risk accepted, compensating control, false positive, not applicable or superseded. You set it on the platform, or from this analysis with Affirm and Disposition…. The analysis reads dispositions when it runs, so a change shows only after Generate again.
What a disposition does to the analysis
| Disposition | In the analysis |
|---|---|
| affirmed, risk accepted, compensating control | The exposure still counts. Accepting or compensating a risk changes no fact in the model. A finding that rests on the exposure names the disposition |
| false positive, not applicable, superseded | The exposure is left out of the analysis. A route that rested on it reads absent, with the label dispositioned, and the exposure is no longer among the exposures inside a finding. If that leaves a required leg absent, the finding is no longer raised |
Two kinds of disposition count as none:
- Stale: the exposure changed after the disposition was set.
- Unstamped: no one or no time is recorded for the disposition, because it was set outside the platform's own flow.
A disposition acts only on an exposure the platform raised. Some footholds are derived from the model's topology instead, for example an agent that untrusted content reaches and that has a code or file tool. No disposition removes such a foothold. Change the model, then click Generate again.
Where a disposition shows
The disposition chip. In the exposure dialog, on each exposure row of the element dialog, and on an expanded exposure row on Findings, an exposure with a disposition shows it in words:
| Chip | Meaning |
|---|---|
| The kind alone, for example "risk accepted" | The disposition is in force and the exposure still counts |
| "kind · left out of the analysis" | False positive, not applicable or superseded: the exposure is left out |
| "kind · stale, counts as none" | The exposure changed after the disposition was set |
| "kind · unstamped, counts as none" | No one or no time is recorded for the disposition |
In the dialogs, a chip that counts as none is drawn dashed and muted. The words carry the meaning either way.
A finding's Dispositions. An expanded finding, and the finding dialog, end with Dispositions when the finding rests on a dispositioned exposure or left one out. Each line names the exposure and its element, then the disposition, who set it and when, and what it does to this finding:
- "risk accepted by person, time · still counted"
- "false positive by person, time · left out of this finding"
- "affirmed, unstamped (no one or no time recorded) · counts as none"
A left-out exposure is no longer among the exposures inside the finding, so this block is where it is named. Click an exposure to open its dialog. A stale disposition is not listed, because it counts as none.
When the finding's foothold is derived from the model's topology, a note under the dispositions says so: "Its foothold at element is derived from the model's topology, not raised as a platform exposure, so no disposition removes it."
Affirm or disposition an exposure
Affirm and Disposition… sit just after + Risk and + Issue:
- beside the element's name under the title of the exposure dialog
- on each exposure row under In this analysis in the element dialog
An expanded exposure row on Findings has neither. Click Open the exposure to reach its dialog.
To affirm an exposure, click Affirm. The platform affirms it at once. No dialog opens.
To set, change or remove a disposition:
- Click Disposition…. The platform's own disposition dialog opens. It starts from the exposure's disposition as the platform holds it now.
- Choose a kind, or remove the disposition, and save it in that dialog.
After a save:
- pending Generate shows beside the buttons.
- A message at the bottom of the analysis reads "exposure: disposition. This result reads stale until you Generate again.", for example "Prompt injection: false positive. This result reads stale until you Generate again." A removed disposition reads "disposition removed".
- The stale banner shows. Until you click Generate again, the findings, chips and counts show the last run.
If you cancel the platform's dialog, nothing changes and no message shows.
If the platform refuses the change, the message gives its reason: Couldn't save — reason. If the save fails for any other reason, it reads Couldn't save the disposition. Either way nothing is saved, and the message offers Retry.
When the buttons are greyed out. Hover over a button to see why. When they are available, the tooltips read Affirm: confirm this exposure is a real, live risk and Disposition… (opens the platform's dialog).
| Tooltip | Meaning |
|---|---|
| Already affirmed | On Affirm only. The exposure is affirmed and the affirmation is in force, or you affirmed it since the last run. A stale or unstamped affirmation can be affirmed again |
| Unavailable — the host platform is too old for disposition actions | On both buttons. Your platform does not offer disposition actions to Threat Patterns yet. Ask your administrator to upgrade it |
While a save on an exposure is in progress, both of its buttons are greyed out.
By item
By item maps findings to three lists: the OWASP Top 10 for Agentic Applications, the OWASP Top 10 for LLM Applications, and the MITRE ATT&CK and ATLAS tactics. Choose the list under List. Its edition shows beside it.
OWASP lists
In the two OWASP lists, the columns are:
| Column | Shows |
|---|---|
| Item | The item's id and title |
| Assessed | Whether the patterns assess the item: assessed, partly assessed, not assessed: reason (for example "not assessed: emergent system property"), or not assessed: nothing in this model exercises it. The last one means the classes that would show the item are not drawn, or their facts are unanswered |
| Pattern findings | The item's systemic findings, for example "1 pattern finding: 1 Confirmed" |
| Element exposures | The item's exposures by triage, then how many have a control modelled or are detected only, for example "1 analyst-confirmed · 4 untriaged, 5 in all · 2 with a control modelled" |
An empty cell reads none. Click a row to fold it open onto its findings and exposures. Each one starts with its severity chip, in the element dialog's colours: first the findings with their own severity, a Not ruled out finding marked if confirmed as on the Findings tab, then the exposures, the most severe first and then by name. Each one is a link that opens its dialog over By item, so you keep your place. To see it on the Findings tab, click Open in Findings in the dialog. See Dialogs.
An item on the sheet's OWASP Agentic strip opens here, with its row open. See The sheet.
Findings without a reference in the list go to the Unmapped row. The footer says "One finding can sit under several items." It then reminds readers that the OWASP lists are awareness lists, not standards.
MITRE tactics
Choose MITRE ATT&CK and ATLAS tactics under List to see your findings by what an attacker is trying to achieve. There is one row for each tactic in the MITRE ATT&CK and MITRE ATLAS data loaded on your platform. ATT&CK comes first, then ATLAS, each in the order of its matrix, with the rows grouped under MITRE ATT&CK and MITRE ATLAS. A tactic with nothing under it reads none.
A finding falls under a tactic through its techniques:
- An element exposure falls under every tactic of its own ATT&CK and ATLAS techniques.
- A systemic finding falls under the tactics of its pattern's techniques, and of the techniques behind the parts of it that are present in your model. A part the model leaves undetermined or absent adds no tactic.
One technique can sit under several tactics, so one finding can appear in several rows. Within a row it is counted once. The Pattern findings and Element exposures columns read as in the OWASP lists, with the same triage counts and control notes. Click a row to fold it open onto its findings.
No Assessed column. For the OWASP lists, the pattern pack states which items its patterns assess. There is no such statement for tactics: the rows come from the MITRE data, and findings land on them only through their techniques. So a tactic row does not say whether it is assessed. A tactic that reads none means that no finding in this model has a technique under it, nothing more.
Not mapped. The Unmapped row holds what falls under no tactic:
- an element exposure with no technique, for example many monitoring, audit-trail and data-retention exposures
- an element exposure whose techniques sit under no tactic in the loaded MITRE data
- a systemic finding with no tactic
Edition. Your platform does not record which MITRE release it loaded, so the edition names the tactics this run read, for example as loaded (tactics 6904ca3a). The code after "tactics" changes when MITRE data is loaded again with a different list of tactics. Loading MITRE data again does not mark a result as out of date. Click Generate again to see the new tactics.
The footer reads "Tactics come from the MITRE technique mappings of each finding; a finding counts under every tactic of its techniques. This view orients; it is not detection or control coverage."
The tactics list is on the By item tab only. The sheet keeps the OWASP Agentic strip. A result made before the tactics list existed shows the earlier-version message; see Troubleshooting.
Facts to establish
This tab tells you what to add to the model so the analysis can decide. Each question is asked once, for one element and what settles it, however many findings or legs it settles.
- Model gaps are counts with a denominator, such as "2 of 6 agents have no declared outbound flows", with the elements named under it: "on A, B". A gap says how to close it where there is more than one way, for example "agents' W depends on an unanswered harness mode: answer the harness's approval mode, or each agent's own approval of consequential tools". An identity, such as a managed identity, with no credential drawn on it reads, for example, "1 of 3 identities have no token drawn on them: draw the credential each issues, or its reach and what it unlocks stay unseen". With none named, it reads "No gaps these patterns can detect; not an attestation of completeness."
- Open questions on Not ruled out findings lists each Not ruled out finding in the ranking above, with the questions on its undetermined required legs.
- Facts that could raise a finding lists the questions on agents and credentials that have no finding, or a pattern short of one. The questions are grouped by the agents and credentials they settle. The questions that settle the most of them come first.
Read a question
Each question is one sentence, for example "Set the attribute Consequential Tools Present (consequential_tools_present, in Human Oversight)" or "Draw the outbound flows of research-agent". An attribute reads as the model editor's form names it: its title, then its key and the form section it sits in. Until the titles have been read from the platform, or if they cannot be read, the key shows alone. The question's next step is on the right; see Act on a question. A model gap carries a Known gap chip and no button.
- Under a Not ruled out finding, the element the question is on follows the sentence. A line under it says what it settles.
- In Facts that could raise a finding, the element follows as "· on element" only when the sentence does not already name it. The group header says what the questions settle.
- Shared questions. A question several findings share sits under the first-ranked one. The others point to it: "The question "…" is asked under finding."
- Below the bar. A question that also settles agents or credentials without a finding says "also settles, below the bar: …". It is not asked again in the second section.
- Same names. Where two or more elements in the list share a name, a flow reads "name (from A to B)" and another element "name (in parent)", in the question, the element it is on and its next step's dialog. A name no other element shares stays plain, and so does an element with no ends or parent to name.
- Delegation hops. A delegation hop with nothing to ask on its own says "decided by delegate's own legs". Click its questions to show only the delegate's questions. Click show all to clear it.
When both sections are empty, the tab reads "Nothing to establish: every finding is Confirmed, and every agent and credential without one has its legs settled."
Read a group
In Facts that could raise a finding, there is one group per set of agents and credentials the questions settle, and one checklist of items that may be credentials. Each question is in exactly one group.
- Header. It reads "Settles: names", in alphabetical order. A group with more than one question adds "· N questions".
- Order. The group holding the first-ranked question comes first. Within a group, the questions keep the same order.
- Detail. Hover over the header to see, for each agent or credential, the pattern, leg and route its questions settle. Where a question asks whether an item is a credential, the leg reads "whether it is a credential" and the route "an item that may hold a key, token or password".
- Long groups. A group of more than eight questions starts folded. Click ▸ to open it and ▾ to close it.
- Credential checklist. The questions that only ask whether an item is a credential ("Mark whether item is a credential") form one checklist, headed "Contains a key, token or password?" with a count, for example "· 8 items, likeliest first". Under the header it reads "Mark each item that holds a credential. Only a real credential leads a chain on, so the others drop out." The likeliest credentials come first: restricted or confidential items, and items whose name sounds like a secret or a place one is often left, such as configuration, code or memory. The checklist sits where its first question ranks. Click Answer it on each item that holds a credential. A question that also settles something else, for example an agent's private data, stays in the group of what it settles.
Act on a question
Each question carries one next step, by what it asks. The same steps appear on Findings and in the dialogs. None of them writes anything: make the change, then generate again.
| Button | When | The dialog |
|---|---|---|
| Answer it | An attribute, or a field of a data item | Names the element and the fact. Open the model opens it in the model editor |
| Draw it | Something to draw, such as flows, including a route that continues further than the analysis follows | Names what to draw. It says no form answers it, unless the question also offers an attribute to set. Open the model opens the model editor |
| Ask the owner | Nothing in the model answers it yet | Names the question and asks you to put it to whoever owns the element, then draw or set what the answer says. There is no Open the model |
| none | A known gap of the analysis | — |
Assert a fact. Some questions can also be closed by an assertion: a fact you state where the model cannot say it. On Facts to establish, the question then carries a second button, worded for the fact it offers:
| Button | Offered on | You state |
|---|---|---|
| Assert outbound flows complete | An element whose class has no attribute that could state its egress | Every outbound flow of the element is drawn |
| Assert not a hand-off, and B's model never reads it | A flow the model reads as a possible hand-off to agent B. When the flow reaches several agents, the button names them all: "Assert not a hand-off, and B's and C's models never read it" | The flow hands no work on to B, and B's model never reads what it carries |
| Assert H is not assigned to F's compute | A question asking whether identity H serves the compute that F runs on. Each identity gets its own question and button | H is not assigned to the compute F runs on |
- Click the button. A dialog opens, titled Assert: outbound flows complete, Assert: not a hand-off or Assert: identity not on this compute. Its text says what you state and what the next run does with it.
- Enter a Justification (required), at most 2000 characters.
- Click Assert. The dialog closes, the assertion appears under Assertions, and the stale banner shows.
At the next run, the routes that rested on the fact read absent, with the label analyst assertion, and name your assertion. A change to the element the assertion is on makes it stale: for outbound flows complete, a change to the element or its outbound flows; for the other two, a change to the flow or to F. A stale assertion is no longer applied.
If the server refuses the assertion, the dialog shows its reason and stays open. Nothing is recorded. See Troubleshooting.
See also the assertion in the modelling checklist.
Assertions lists every assertion on this analysis with its fact, author, time and justification. The fact reads outbound flows complete, not a hand-off or identity not on this compute: H. An assertion is applied, stale (what it is on changed since) or withdrawn. Use Withdraw to retire one. The entry stays, with who withdrew it.
The modelling checklist lists the common facts and drawings, and what each settles.
The sheet
Sheet is a one-page summary for a CISO, with an appendix for engineers. Every page starts with the sensitivity mark "Sensitive: names where credentials are held and what they unlock".
CISO page
In order, the CISO page shows:
- The title, Threat Patterns · model name.
- The counts: the systemic findings line, one line per pattern (for example "Credential chain: 1 Confirmed · 1 Not ruled out"), then the element exposures line.
- A legend:
- "Confirmed: every required leg of the pattern is present in the model."
- "Not ruled out: at least two required legs are present and none is absent; the rest are open questions, answered on the Facts to establish tab."
- "Severity is the pattern's band, not business impact."
- The triage coverage line: "triage coverage: R of N exposures reviewed (P%) — element exposures only, as of time; review progress, not a security measure". N is every element exposure, dispositioned ones included, and R those with any disposition. The line is left out when the model has no exposures.
- Top findings: the top three, under the ranking rule. Each gives the band (with "if confirmed" for a Not ruled out finding), Confirmed or Not ruled out, and the coverage with the credited legs it names, as on the Findings tab, for example "control modelled on P". The exported sheet shows the same words. Then "pattern at subject", the pattern's reason and "Runs through elements". A Not ruled out finding adds how many questions stand open on the Facts to establish tab. On screen, the finding's title and its coverage word, for example unmitigated, carry the same tooltips as on the Findings tab: the pattern with its band, reason and legs, and what the word means. Hover over them or move to them with Tab. See Tooltips.
- Top fixes: the top three changes, grouped as on the Fixes tab, each with its owner, what it breaks, and its or instead: alternatives. A partial fix among them reads "narrows, does not close; if it cut those routes it would: …", as on the Fixes tab.
- Model gaps, with the same no-gaps wording as the Facts to establish tab.
- The OWASP Agentic strip: each item's id with its short name under it (for example "ASI01" and "Agent Goal Hijack"), its Assessed wording and its findings, then how many findings have no reference in the list, and "One finding can sit under several items." On screen, the note adds "Each item opens on the By item tab." Click an item, or move to it with Tab and press Enter, to open its row on By item under the OWASP Agentic list, expanded and scrolled into view. The address keeps the item while you stay on By item, so a reload or a shared address opens the same row. If the result no longer holds that item, the tab opens with no row open.
- The provenance line: the pattern packs and versions, the generated time, the fingerprint ("fingerprint of the model, engine and credit table sha256:…") and how many analyst assertions were applied. The fingerprint is what marks a result out of date; see Run the analysis.
Engineer appendix
- Top findings, leg by leg: the same top three, each required leg with its state and the elements that supply it.
- The rotate list: one row per credential in a credential chain, with Holders, Wielders, Unlocks and Owner (the issuer).
- The pattern versions.
The exported file adds the legs of every finding and the facts to establish, each question listed once.
The analysis never treats a missing field as a secure answer: an unanswered fact is undetermined, never assumed safe.
Export the sheet
Click Export sheet (HTML, print to PDF) to download a printable HTML file. It has no tooltips, and its strip items open nothing. Under its title it names each pattern pack the engine did not run, in the words of the notice above the report; see Run the analysis. For a PDF, open it and use your browser's Print. In print, the sensitivity mark repeats at the top of every printed page. The sheet names where credentials are held and what they unlock, so handle it as sensitive.
What the analysis does not claim
- It reads your model, not your running systems. A missing leg may be a fact you have not drawn yet.
- It shows no all-clear, and counts always carry a denominator. The only percentage is the sheet's triage coverage. It describes how far review of the exposures has got, not security.
- A control in the model reads control modelled. That says nothing about how well the control works in practice.
- The By item lists orient readers. The OWASP lists are not an attestation, and the tactics list is not detection or control coverage.
Troubleshooting
| You see | What to do |
|---|---|
| Threat Patterns is not in the New Analysis menu | The analysis is not installed on your platform. Contact your administrator |
| No pattern pack is installed, so no pattern was evaluated. | Ask your administrator to install the agentic pattern pack, then click Generate again |
| Few findings and a long Facts to establish list | The model does not state enough yet. Work through the modelling checklist |
| No Origin or Credential field on data items | Your platform is older than 0.11.0. Results are partial until it is upgraded |
| This result was made by an earlier version of Threat Patterns. Generate again to read it. | The analysis was updated since the last run. Click Generate again |
| By item has no MITRE ATT&CK and ATLAS tactics list | Your platform has no MITRE ATT&CK or ATLAS data loaded. Contact your administrator |
| An assertion shows stale | What it is on changed: the element or its outbound flows, the flow, or the element whose compute it names. Check the model again, then withdraw it or assert again |
| The assertion dialog shows "flow is not a possible hand-off in the model: there is nothing to assert" | The model does not read the flow as a possible hand-off, so there is nothing to settle. Nothing was recorded. Click Cancel |
| The assertion dialog shows "flow is drawn as a hand-off: redraw it if it is not one", or "… drawn as a hand-off between two agents: …" | The model already reads the flow as a hand-off from how it is drawn. An assertion cannot override the drawing. If the flow is not a hand-off, redraw it in the model, then click Generate again |
| A notice reads Pattern pack pack@version needs the Threat Patterns engine version or later; … | The engine skipped that pack, so its findings are missing. Ask your administrator to upgrade the Threat Patterns engine module, then click Generate again |
| Affirm and Disposition… are greyed out: Unavailable — the host platform is too old for disposition actions | Your platform does not offer disposition actions to Threat Patterns yet. Ask your administrator to upgrade it |
| Couldn't save — reason. or Couldn't save the disposition. | Nothing was saved. Read the platform's reason, if there is one, then click Retry on the message. If it keeps failing, contact your administrator |
| A run fails | The previous result stays. Try again; if it keeps failing, contact your administrator |
| A fix reads compensate or accept on an element you run | The element's Operated by is set to A vendor, or it is empty and the element sits in a vendor's zone, or the boundary it is drawn in says a vendor runs its environment. If you know you run it, set Operated by to You (your organisation) on the element or the boundary, then click Generate again. See Answer who runs an element |
| A fix carries who holds it depends on: | The model does not say who runs the element it names. Answer Operated by there if you know; otherwise leave it empty and ask the element's owner |
| + Issue is greyed out: Unavailable — the host platform is too old for issue actions | Your platform does not offer issues to Threat Patterns yet. Ask your administrator to upgrade it |
| Couldn't open the issue workflow. | No issue was raised. Try again; if it keeps failing, contact your administrator |
| + Risk is greyed out: Unavailable — the risk register comes with Risk Assessment | Risk Assessment is not installed on your platform. Contact your administrator |
| + Risk is greyed out: Unavailable — this platform's Risk Assessment does not take Threat Patterns findings yet | Your Risk Assessment is too old to take Threat Patterns findings. Ask your administrator to upgrade it |
| + Risk on an exposure is greyed out: Unavailable — this platform's Risk Assessment does not take Threat Patterns exposures yet | Your Risk Assessment takes Threat Patterns findings but not yet exposures. Ask your administrator to upgrade it |
| Couldn't save the risk. | Nothing was saved. Try again; if it keeps failing, contact your administrator |
| Couldn't confirm it still stands as shown, so nothing was saved. | Threat Patterns could not read the finding or exposure as it stands, or the exposure is no longer on its element as it was, so no risk or evidence was saved. Try again. For an exposure, click Generate again first to see whether it still stands. If it keeps failing, contact your administrator |
Related guides
- Modelling checklist: what to set and draw so the legs can be decided.
- Model an agentic architecture: a hands-on training that builds one agentic system step by step and runs Threat Patterns after each step.
- Risk Assessment: the risk report and register for the same model.
- The Risk Register: rate, treat, accept and close the risks you record from a finding or an exposure.
