Threat Model Data Flow Diagram

Processes, stores and flows with trust boundaries drawn across them, so that every boundary crossing can be enumerated for threats.

Technology Cloud-Agnostic
flowchart LR
  user(["Customer<br/><i>untrusted</i>"])
  admin(["Admin<br/><i>privileged</i>"])

  subgraph edge["Boundary 1 — public edge"]
    cdn["CDN / WAF"]
  end

  subgraph app["Boundary 2 — application tier"]
    direction TB
    api["Order API"]
    auth["Auth Service"]
  end

  subgraph datab["Boundary 3 — data tier"]
    direction TB
    db[("Order Store<br/><i>PII + card token</i>")]
    kms[("Key Vault")]
  end

  ext["Payment Provider<br/><i>third party</i>"]

  user -->|"F1 HTTPS"| cdn
  cdn -->|"F2 HTTPS + mTLS"| api
  admin -->|"F3 admin console"| api
  api -->|"F4 token introspection"| auth
  api -->|"F5 TLS + parameterised"| db
  api -->|"F6 fetch DEK"| kms
  api -->|"F7 HTTPS outbound"| ext
  ext -->|"F8 webhook — signed"| cdn

What it is

A data flow diagram with trust boundaries drawn across it. The processes, stores and flows are ordinary; the dashed boundaries are what turn it into a security artifact. Every flow that crosses a boundary is numbered, and each numbered crossing gets walked through a threat taxonomy — spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege — producing a finding or an explicit "not applicable, because".

When you produce it

At design time, when the mitigation is a design choice rather than a patch, and again whenever a new external integration or a new class of data appears. The inbound webhook in the example is exactly the flow that gets added later and never re-modelled.

Who reads it

Security architects, who drive the session. The engineering team, who must be in the room — a threat model produced without them is a document, not a control. Auditors, who ask to see it and to see what came out of it.

What good looks like

  • Flows are numbered and the numbers are referenced by the findings table.
  • Boundaries reflect real differences in trust, not diagram tidiness.
  • Data sensitivity is annotated on the stores.
  • Inbound flows from third parties are drawn — a webhook is an inbound flow from an untrusted source no matter who sends it.
  • The output is a findings list with owners, not a picture.

Common mistakes

  • No boundaries. Then it is a data flow diagram and the analysis has nowhere to attach.
  • Only outbound third-party flows. Callbacks and webhooks are the ones that get missed.
  • Modelling the whole estate. Scope it to one system and one release, or it never finishes.
  • Producing the diagram and stopping. The diagram is the input; the findings and their owners are the deliverable.