---
title: 'Diamond Model'
source: 'https://academia.sh/en/courses/attack-techniques/diamond-model'
course: 'Attack Techniques and the Threat Landscape'
language: en
updated: '2026-09-26T03:02:49+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Models an event with actor, infrastructure, capability, and victim corners and counts the links of the corner pairs'
    - 'Measures how many candidates knowing one corner leaves in the other corners by running the model'
    - 'Ranks narrowing power together with its visibility cost and derives the gain of adding a second corner'
---

# Diamond Model

Translating the four-corner relationship model into a link count: the actor, infrastructure, capability, and victim corners fill 77 of 134 possible links across 20 observations; the narrowing ratio of knowing one corner comes out exactly equal to that corner pair's link sparsity; the strongest corner (50%) becomes visible at the chain's eighth step and only after 41 items; the earliest-visible corner narrows only 30.7%; the capability corner gives 43.1% narrowing at a cost of 1 item; and adding a second corner adds only 10 to 13.1 points to the narrowing.

The matrix left one question unanswered. Cells say "this step can be carried out through this
technique" and record whether a control sees that technique. But once an observation is in hand —
a record, a connection, a file trace — **which event that observation belongs to** cannot be read
from the matrix. The same technique class occurs in many independent events.

A second structure fills this gap and names an event by four corners: **who** (actor profile),
**through which infrastructure**, **with which capability**, and **against whom**. Four corners
produce six pairwise links, and the claim the model carries is this: when one corner is known, the
others narrow. This lesson measures that narrowing as a **link count**.

## Four Corners, Six Links

The observation set below is **fictional**: no real actor, infrastructure item, campaign, or
organization name appears; the actor corner is written only by capability and motivation level.

**TM13:** an observation records four corners together, and the four corners produce six pairwise
links. **TM14:** knowing a corner means staying confined to the observations that carry that
value; the remaining candidate count is the number of distinct values of the target corner in that
subset. **TM15:** every corner becomes visible at a particular step of the chain, and the item
count reached by that step is the cost of using that corner.

```js
// threat/corner.mjs — data structure of the four-corner relationship model: every observation ties together an
// event's four corners. The observations are fictional; no real actor, infrastructure item, campaign, or
// organization name appears. The actor corner is written only by capability and motivation level.

// TM13: an observation records four corners together: actor profile, infrastructure item,
// capability (technique class), and victim item. Four corners produce 6 pairwise links.
export const CORNER = ["actor", "infrastructure", "capability", "victim"];
export const OBSERVATION = `
  capability-2-revenue          shared-hosting          attachment-based                branch-endpoint
  capability-2-revenue          shared-hosting          attachment-based                subscriber-portal
  capability-2-revenue          open-proxy              valid-credential-login          subscriber-portal
  capability-2-revenue          shared-hosting          valid-credential-login          branch-endpoint
  capability-2-revenue          open-proxy              attachment-based                field-application
  capability-3-revenue          shared-hosting          external-service-exploitation   subscriber-portal
  capability-3-revenue          rented-endpoint         external-service-exploitation   billing-service
  capability-3-revenue          rented-endpoint         interpreter-invocation          billing-service
  capability-3-revenue          open-proxy              attachment-based                field-application
  capability-3-revenue          shared-hosting          valid-credential-login          subscriber-portal
  capability-3-insider-access   own-endpoint            credential-reuse                field-application
  capability-3-insider-access   own-endpoint            valid-credential-login          billing-service
  capability-3-insider-access   own-endpoint            credential-reuse                billing-service
  capability-3-insider-access   own-endpoint            encrypted-channel               branch-endpoint
  capability-5-targeted         compromised-endpoint    external-service-exploitation   field-application
  capability-5-targeted         compromised-endpoint    interpreter-invocation          field-application
  capability-5-targeted         compromised-endpoint    credential-reuse                billing-service
  capability-5-targeted         compromised-endpoint    encrypted-channel               branch-endpoint
  capability-5-targeted         rented-endpoint         encrypted-channel               billing-service
  capability-5-targeted         rented-endpoint         interpreter-invocation          subscriber-portal`
  .trim().split("\n").map((r) => {
    const [actor, infrastructure, capability, victim] = r.trim().split(/\s+/);
    return { actor, infrastructure, capability, victim };
  });

export const value = (k) => [...new Set(OBSERVATION.map((g) => g[k]))];

// TM14: knowing a corner means staying confined to observations that carry that value; the remaining
// candidate count is the number of distinct values of the target corner in that subset, averaged over the groups.
export function narrow(known, target) {
  const total = value(target).length;
  const groups = new Map();
  for (const g of OBSERVATION) {
    const key = known.map((k) => g[k]).join("|");
    if (!groups.has(key)) groups.set(key, new Set());
    groups.get(key).add(g[target]);
  }
  const avg = [...groups.values()].reduce((t, s) => t + s.size, 0) / groups.size;
  return { avg, total, ratio: 1 - avg / total, group: groups.size };
}

// TM15: every corner becomes visible at a particular step of the chain; the item count reached by
// that step is the cost of using that corner. The actor corner is never directly visible; it is inferred.
export const VISIBILITY = { victim: { step: "initial-access", items: 0 },
  capability: { step: "execution", items: 1 }, infrastructure: { step: "exfiltration", items: 41 },
  actor: { step: "-", items: null } };
```

```js
// threat/pivot.mjs — how many candidates knowing one corner eliminates from the others.
import { CORNER, OBSERVATION, value, narrow, VISIBILITY } from "./corner.mjs";

const print = (w, ...s) => console.log(s.map((v, i) =>
  (w[i] < 0 ? String(v).padEnd(-w[i]) : String(v).padStart(w[i]))).join(""));
const pair = CORNER.flatMap((a, i) => CORNER.slice(i + 1).map((b) => [a, b]));
const possible = pair.reduce((t, [a, b]) => t + value(a).length * value(b).length, 0);
const seen = pair.reduce((t, [a, b]) =>
  t + new Set(OBSERVATION.map((g) => `${g[a]}|${g[b]}`)).size, 0);

console.log(`${OBSERVATION.length} observations, ${CORNER.length} corners ` +
  `(${CORNER.map((k) => `${k} ${value(k).length}`).join(", ")}); ` +
  `${pair.length} corner pairs, ${possible} possible links, ${seen} present in the observations ` +
  `(${((seen / possible) * 100).toFixed(1)}%)`);

const A = [-16, -16, 10, 11, 13];
console.log("\n1. corner pairs: how many links are present in the observations");
print(A, "corner", "corner", "possible", "present", "sparsity %");
for (const [a, b] of pair) {
  const n = new Set(OBSERVATION.map((g) => `${g[a]}|${g[b]}`)).size;
  const o = value(a).length * value(b).length;
  print(A, a, b, o, n, (100 - (n / o) * 100).toFixed(1));
}

const B = [-16, -16, 8, 16, 13, 8];
console.log("\n2. how many candidates remain in the other corner once one is known");
print(B, "known", "target", "total", "avg candidates", "narrowing %", "group");
for (const b of CORNER) for (const h of CORNER) {
  if (b === h) continue;
  const d = narrow([b], h);
  print(B, b, h, d.total, d.avg.toFixed(2), (d.ratio * 100).toFixed(1), d.group);
}

const C = [-16, -16, 15, 17, 6];
console.log("\n3. which corner becomes visible when, and how much it narrows");
print(C, "corner", "visible step", "items by then", "avg narrowing %", "rank");
const strength = CORNER.map((k) => ({ k, g: CORNER.filter((h) => h !== k)
  .reduce((t, h) => t + narrow([k], h).ratio, 0) / (CORNER.length - 1) }))
  .sort((x, y) => y.g - x.g);
for (const { k, g } of strength)
  print(C, k, VISIBILITY[k].step, VISIBILITY[k].items ?? "inferred",
    (g * 100).toFixed(1), strength.findIndex((x) => x.k === k) + 1);

const D = [-30, -16, 16, 13, 9];
console.log("\n4. what a second corner buys");
print(D, "known corner(s)", "target", "avg candidates", "narrowing %", "added %");
for (const h of CORNER) {
  const single = CORNER.filter((k) => k !== h)
    .map((k) => ({ k, d: narrow([k], h) })).sort((x, y) => x.d.avg - y.d.avg)[0];
  const other = CORNER.filter((k) => k !== h && k !== single.k);
  const pairD = narrow([single.k, other[0]], h);
  print(D, single.k, h, single.d.avg.toFixed(2), (single.d.ratio * 100).toFixed(1), "-");
  print(D, `${single.k} + ${other[0]}`, h, pairD.avg.toFixed(2), (pairD.ratio * 100).toFixed(1),
    ((pairD.ratio - single.d.ratio) * 100).toFixed(1));
}
console.log("if three corners are known, remaining average candidates: " + CORNER.map((h) =>
  `${h} ${narrow(CORNER.filter((k) => k !== h), h).avg.toFixed(2)}`).join(", "));

const best = strength[0];
console.log(`strongest corner ${best.k} (${(best.g * 100).toFixed(1)}%), ` +
  `visible at the ${VISIBILITY[best.k].step} step and by then ` +
  `${VISIBILITY[best.k].items} items have been reached; earliest-visible corner ` +
  `victim (${VISIBILITY.victim.items} items) and its narrowing ` +
  `${(strength.find((x) => x.k === "victim").g * 100).toFixed(1)}%`);
```

```
20 observations, 4 corners (actor 4, infrastructure 5, capability 6, victim 4); 6 corner pairs, 134 possible links, 77 present in the observations (57.5%)

1. corner pairs: how many links are present in the observations
corner          corner            possible    present   sparsity %
actor           infrastructure          20          8         60.0
actor           capability              24         13         45.8
actor           victim                  16         13         18.8
infrastructure  capability              30         15         50.0
infrastructure  victim                  20         12         40.0
capability      victim                  24         16         33.3

2. how many candidates remain in the other corner once one is known
known           target             total  avg candidates  narrowing %   group
actor           infrastructure         5            2.00         60.0       4
actor           capability             6            3.25         45.8       4
actor           victim                 4            3.25         18.8       4
infrastructure  actor                  4            1.60         60.0       5
infrastructure  capability             6            3.00         50.0       5
infrastructure  victim                 4            2.40         40.0       5
capability      actor                  4            2.17         45.8       6
capability      infrastructure         5            2.50         50.0       6
capability      victim                 4            2.67         33.3       6
victim          actor                  4            3.25         18.8       4
victim          infrastructure         5            3.00         40.0       4
victim          capability             6            4.00         33.3       4

3. which corner becomes visible when, and how much it narrows
corner          visible step      items by then  avg narrowing %  rank
infrastructure  exfiltration                 41             50.0     1
capability      execution                     1             43.1     2
actor           -                      inferred             41.5     3
victim          initial-access                0             30.7     4

4. what a second corner buys
known corner(s)               target            avg candidates  narrowing %  added %
infrastructure                actor                       1.60         60.0        -
infrastructure + capability   actor                       1.20         70.0     10.0
actor                         infrastructure              2.00         60.0        -
actor + capability            infrastructure              1.38         72.3     12.3
infrastructure                capability                  3.00         50.0        -
infrastructure + actor        capability                  2.25         62.5     12.5
infrastructure                victim                      2.40         40.0        -
infrastructure + actor        victim                      1.88         53.1     13.1
if three corners are known, remaining average candidates: actor 1.05, infrastructure 1.00, capability 1.33, victim 1.11
strongest corner infrastructure (50.0%), visible at the exfiltration step and by then 41 items have been reached; earliest-visible corner victim (0 items) and its narrowing 30.7%
```

The numbers are in the **measurement** class; their inputs are TM13–TM15.

## Narrowing Is a Sparsity Measure

The four corners' value counts are 4, 5, 6, and 4. The six corner pairs define a total of **134
possible links**; 20 observations fill **77 of them**. The remaining 57 links are never seen at
all, and the model's whole power comes from there.

Reading the second table alongside the first reveals an equality: every corner pair's **sparsity
percentage** turns out **exactly equal to the narrowing percentage** calculated for that pair. The
actor-infrastructure pair's sparsity is 60.0%; knowing the actor narrows infrastructure by 60.0%,
and knowing infrastructure narrows the actor by 60.0% as well. The actor-victim pair's sparsity is
18.8%, and so is its narrowing.

The equality is not a coincidence. For every value of a corner, the sum of the remaining candidate
counts is exactly the number of distinct links in that pair; dividing by the group count gives the
average candidate, and relating that to the target corner's total value count yields link density.
**Narrowing power is how empty the link matrix is.** The model is therefore not an intuition but
something countable: the fewer combinations that have occurred between two corners, the more
knowing one narrows the other.

The warning that follows from this is on the same scale. As the observation count grows, the link
matrix fills, and narrowing power **falls**. A growing observation pool does not automatically
strengthen inference; once the matrix starts filling, the same corner discriminates less.

## The Strongest Corner Is the Most Expensive Corner

The third table is this lesson's central comparison: every corner's average narrowing power is
written side by side with the step at which it becomes visible in the chain.

**Infrastructure** heads the ranking: it narrows the other three corners by an average of 50.0%.
But the infrastructure corner only becomes visible at the exfiltration step — the external
endpoint shows up as data leaves — and by that point **41 items** have been reached. The strongest
clue is born at the chain's latest link.

This late birth comes from the model's own structure. The infrastructure corner is strong because
its link matrix with the actor is the emptiest one — every actor profile uses only a few forms of
infrastructure. That same sparsity is also why this corner appears late on the defense side: a
sparsely used item only falls into a record at the chain's end, on an outward-facing step.

**Victim** sits at the bottom of the ranking: 30.7% narrowing. This corner is free on the defense
side, because which item is targeted is already clear at the initial-access step, and at that
point **0 items** have been lost. The free one is the weakest; the strongest one is the most
expensive.

The row in between makes the call. **Capability** narrows 43.1% and becomes visible at the
execution step — the items reached by then are **1**. Infrastructure's 6.9-point edge costs 40
more items. Measured by the chain's own scale, the best corner is not the one that narrows the
most but the one that **narrows the most per item spent**; on that measure the capability corner
is thirty-five times more efficient than infrastructure. The victim corner is free, so no such
ratio can be formed for it; what sets it apart is not efficiency but having the lowest narrowing
of all.

There is also an asymmetry inside the second table itself. Even though the narrowing percentage is
equal in both directions for the same pair, the **remaining candidate count** is not: knowing
infrastructure brings the actor down from 4 candidates to 1.60, knowing the actor brings
infrastructure down from 5 to 2.00. The percentage is the same, the absolute number is different,
and the decision is made with the absolute number. Targeting the corner with the smaller value set
produces a more precise result at the same sparsity.

The actor corner stands apart in the table: it is never directly visible at any step; it is
inferred from the other three corners. Its narrowing power is 41.5%, but this power is only
meaningful as a target of inference — knowing the actor narrows the other corners, but the only
way to know the actor is through the other corners.

## The Return of a Second Corner

The fourth table finds the best single pivot for every target corner, then adds a second corner to
it.

The best single corner for narrowing the actor is infrastructure: it drops from four candidates to
**1.60** (60.0%). Adding the capability corner brings it down to 1.20 (70.0%) — the second corner's
contribution is **10 points**. In the other three rows the added contribution is 12.3, 12.5, and
13.1 points. In all four cases, the second corner brings roughly **one-sixth** as much extra
narrowing as the first.

The reason for the diminishing return is in the first table. The second corner only works within
the subset the first one leaves behind, and that subset is already sparse; the number of links the
second pivot can still remove is far smaller than what the first removed. The last row shows the
limit: once three corners are known together, the remaining average candidate is between 1.00 and
1.33 — meaning nothing is left to add after the third corner.

This writes how the four-corner model is used in practice. The first pivot delivers nearly all of
the decision; the second pivot is a verification tool. Going from 1.60 to 1.20 on the actor corner
means, on average, "one candidate" instead of "two candidates," and this difference is decisive on
some observation sets — but if it is bought at the cost of waiting 40 more items, **the price paid
is larger than the narrowing gained**.

Put on the chain's scale: waiting for one more corner means advancing one more step in the chain.
With the previous lesson's numbers, that wait — going from execution to exfiltration — means moving
from 1 item to 41 items. **The relationship model delivers narrowing, but the narrowing's cost
carries no decision unless it is written on the chain's own scale.**

## Summary

- Four corners (actor, infrastructure, capability, victim) produce six pairwise links; 20
  observations fill 77 of 134 possible links, and the remaining 57 gaps supply the model's entire
  power.
- The narrowing percentage of knowing a corner is exactly equal to that corner pair's link sparsity;
  narrowing power is how empty the link matrix is.
- As the observation count grows, the matrix fills and narrowing power falls; growing the pool does
  not strengthen inference by itself.
- The strongest corner is infrastructure (50.0%), but it becomes visible at the exfiltration step,
  after 41 items; the earliest-visible corner is the victim (0 items), and it narrows only 30.7%.
- The capability corner narrows 43.1% at a cost of 1 item; infrastructure's 6.9-point edge costs 40
  more items.
- The second corner's contribution is between 10.0 and 13.1 points — roughly one-sixth of what the
  first pivot provides; the first pivot makes the decision, the second verifies it.

## Next Step

Everything measured across five lessons stood on the same assumption: what the controls saw were
things **known in advance**. Every cell in the matrix was tied to a technique class, every control
item to a recognized record pattern; every corner in the relationship model rested on a link that
had been seen before.

The moment a technique is used for the first time, though, falls outside this assumption. There is
not yet a pattern to recognize, that row in the link matrix is empty, and no fix has been released
either. The topic's final lesson measures this situation in terms of coverage: of the links that
can be broken under a known threat, how many can still be broken under an unknown threat; how many
steps a signature-based control misses; how many a behavior-based control still catches; and how
many items stay exposed in the window until a fix is published.
