skip to content

Modeling Real Architectures

Threat modeling worked against named system shapes: a browser app, an API estate, a serverless workload, a build pipeline, a device, a vendor integration. Senior interviews run this live.

on this pageshow

explore

questions

23

When threat-modeling a web app, why is the browser drawn as an external entity outside your trust boundary?

level: juniorimportance: must knowfreq 78%

answer

  1. you do not run this element
  2. it lives on the user's machine
  3. everything inbound is authored
  4. client checks are UX, not controls
  5. external entity: spoofing and repudiation

basics

~20 s

The browser runs on the user's machine, so every field, header and request sequence it sends is attacker-authorable. Draw it outside your trust boundary: it is an input source, never a place where a rule is enforced.

solid answer

~50 s

On a data-flow diagram the browser is an external entity: something you interact with but do not run. The trust boundary sits at your server's request-handling edge, and everything crossing it inbound is authored by whoever controls the client - visible fields, hidden ones, headers, the order requests arrive in, and whether a human was involved at all. That makes client-side validation, disabled buttons and a hidden amount field usability features rather than controls; a model that credits them has invented a mitigation that does not exist. On a municipal parking-fine site with an anonymous 'pay without an account' flow, the posted fee is a claim, so the handler recomputes it from the fine record and ignores what arrived. In STRIDE-per-element terms the external entity attracts spoofing and repudiation, while the flow crossing the boundary attracts tampering and information disclosure.

go deeper

for a junior

Be ready to say in one sentence that the browser sits outside the boundary because you do not run it, and to give one concrete check that must therefore be repeated on the server.

for a middle

Explain what the placement implies mechanically: which flows carry attacker-authored data, why each handler re-derives its own facts, and which STRIDE categories attach to an external entity versus the flow crossing the line.

for a senior

Show that you can spot invented mitigations in someone else's model - a threat rated low because the UI prevents it - and describe how you verify that a claimed control actually executes server-side.

for a principal

Own the standard your teams model to, so a portfolio of diagrams does not accumulate risk ratings that rest on behaviour a user can edit. Decide how client-side behaviour is recorded and reviewed.

## What a trust boundary is actually grouping A data-flow diagram used for threat modeling is not a deployment picture. It groups elements by **who runs them and under whose authority they execute**. A trust boundary is the line where that answer changes, and its whole purpose is to mark the crossings where data or a request moves from one level of trust to another - because those crossings are where you have to do work. A browser is the cleanest example available. You wrote the page it loaded; you do not run the thing that executes it. It sits on a laptop you have never seen, under an operating system you do not patch, next to extensions you did not install, and its developer tools are one keypress away. That is the entire argument: **placement follows control, not code authorship**. The JavaScript is yours, the execution is not. ## What follows mechanically Once the browser is outside, everything on the inbound flow is a *claim*, not a fact: - Form fields, including hidden ones and ones a `disabled` attribute greyed out. - Headers, and any value a page put in one. - Which endpoint is called, in which order, and how fast. - Whether the request came from your page at all - the same HTTP request can be produced by a script that never rendered your UI. So the model must treat every inbound flow as untrusted input and ask, per crossing: what is validated here, and where is the authority for this decision. On a parking-fine site, the anonymous payment flow posts a fine reference and an amount. The amount is not data the server may use; it is a suggestion. The server looks up the fine and computes the fee itself. If the model records 'the page only offers the correct amount' as the mitigation, the threat is live and the risk rating is a fiction. The asset here is money, and the attacker is an anonymous member of the public - no account, no privileges, nothing to compromise first. ## The invented-mitigation failure The most common defect in a first web-app model is not a missed threat; it is a **credited control that runs on the attacker's side of the line**. It looks like this: | Claimed mitigation | Where it runs | What it is worth | | --- | --- | --- | | Client-side field validation | Browser | Usability. Zero. | | Disabled or hidden submit button | Browser | Usability. Zero. | | Hidden form field carrying a price or role | Browser | Worse than zero - it advertises the parameter. | | A multi-step wizard that enforces order | Browser | Zero; steps can be called directly. | | Server recomputes the value from its own records | Server | The actual control. | Keep the client-side checks - they give instant feedback and cut junk traffic - but record them in the model as user experience. The defect is not having them; it is listing one as the answer to a tampering threat and then rating that threat down. ## TLS does not move the line A second recurring mistake is treating HTTPS as though it made the browser trusted. Transport security protects a flow **in transit** against a third party: it gives confidentiality and integrity between the two endpoints, plus server authentication. It says nothing about whether the endpoint at the other end is honest, and it certainly does not stop the person operating that endpoint from editing what they send. An attacker's own requests are encrypted too. On the diagram, TLS annotates the flow; it does not move the boundary. ## Which threat categories attach here In STRIDE-per-element analysis, element type determines which of the six categories are worth enumerating: - **External entity** (the browser, the user behind it): **spoofing** - is this identity what it claims to be - and **repudiation** - can this party later deny having acted. - **Data flow** (the request and response crossing the boundary): **tampering**, **information disclosure**, **denial of service**. - **Process** (your request handler): all six. - **Data store**: tampering, information disclosure, denial of service, plus repudiation where the store is the log that has to prove what happened. Each category names a violated property: spoofing violates authentication, tampering violates integrity, repudiation violates non-repudiation, information disclosure violates confidentiality, denial of service violates availability, elevation of privilege violates authorization. Naming the property is what turns a category into a testable requirement. ## How to draw it Put the browser at the left as an external entity, draw one boundary around what you run - the handler process and its stores - and let every request and response cross that single line. Resist drawing the boundary around 'the internet': a boundary that separates nothing you can act on tells you nothing. The value of the line is that it forces the next question for each crossing, which is what the rest of the model is built on: what does this handler verify about this request before it acts on it, and does that verification live on my side of the line.

  • A native mobile client and a script hit the same endpoints. Does the diagram change?
    Not in substance. They are the same class of element: things you do not run, sending requests you must treat as authored. Add them as separate entities if their identity or authentication differs, but the boundary and the server-side checks are identical. Anything that would only hold for a well-behaved browser was never a control in the first place.
  • If client-side validation is not a security control, why keep it?
    Because it is a usability and cost feature: instant feedback, fewer round trips, less junk load. Keep it and record it in the model as user experience. The defect is listing it as the mitigation for a tampering threat and rating the risk down on that basis, which leaves a live threat looking handled.
  • Where exactly does the trust boundary line go for a server-rendered app?
    Around the code you run - the request handler, its process, its data stores - so that every inbound request and every response crosses it. Drawing it around 'the internet' makes it useless, because it stops telling you which specific flows need validation and authorization at the moment they arrive.

The browser is the form you hand a customer at a service window. You can print the boxes, but you cannot stop them writing whatever they like inside. The clerk on your side of the glass still checks every field before acting.

saying these in an interview costs you the question

  • Says TLS makes data arriving from the browser trustworthy
  • Counts client-side validation as a mitigation and rates the risk down
  • Assumes requests arrive in the order the UI allows
  • Draws the browser as a process inside the trust boundary
  • Thinks hidden fields and disabled buttons hide values from the user

context

open as a page

When threat-modeling a multi-tenant API, where does the trust boundary sit and which STRIDE categories dominate?

level: middleimportance: must knowfreq 70%

basics

~10 s

In a multi-tenant API the deciding boundary is not the network edge but every endpoint, where an authenticated caller's tenant claim meets shared tenant-owned data. Information disclosure and elevation of privilege dominate the result.

open as a page

A field-service app ships an integration API key inside its package — which threats does that create on a lost handset?

level: middleimportance: must knowfreq 74%

basics

~20 s

Anything shipped inside an app package is readable by whoever holds a copy, so treat that key as public. Two assets are exposed: a fleet-wide credential an attacker can replay against your API, and the customer data cached on a device you do not own.

open as a page

A payroll vendor holds a standing tunnel into your HR database for a nightly sync — where does the trust boundary go?

level: middleimportance: must knowfreq 62%

basics

~20 s

At your side of the tunnel. Everything arriving through it is untrusted input from a system you do not run, so the vendor stays outside your boundary even though the connection is private and encrypted.

open as a page

How do you draw a data-flow diagram for a serverless architecture with no host to put on it?

level: middleimportance: must knowfreq 64%

basics

~20 s

Use the same four DFD elements: functions and managed-service calls are processes; buckets, tables and queues are data stores; event sources are external entities. Draw trust boundaries where the calling identity changes, not where a machine or network ends.

open as a page

In a shared Kubernetes cluster, which of namespace, pod and node is a real trust boundary?

level: middleimportance: must knowfreq 60%

basics

~20 s

The node is the hard line, because pods on one node share its kernel, its disk and its credential. A namespace is an administrative scope the control plane enforces above the API, so it stops nothing that travels below it.

open as a page

How do you draw a build-and-deploy pipeline as a data-flow diagram, and where do its trust boundaries go?

level: middleimportance: must knowfreq 66%

basics

~20 s

Treat the pipeline as the system: external entities (contributors, approvers, upstream registries), processes (trigger, build job, deploy job), stores (source repo, secret store, artifacts, runner disk). Put trust boundaries where trust actually changes — untrusted contribution entering the build, and the build reaching production credentials.

open as a page

A game client computes currency balances locally and reports totals to your server — how do you threat-model it?

level: seniorimportance: must knowfreq 65%

basics

~20 s

Put the trust boundary between the device and your API. Anything the client computes is an assertion, not a fact, so the server must re-derive the balance from state it holds. The client-side calculation is user-experience, not a control.

open as a page

Your public repo builds fork pull requests in a job that can read the deploy secret. What threat does that create?

level: seniorimportance: must knowfreq 54%

basics

~20 s

An anonymous contributor's first pull request becomes attacker-authored code running inside your trusted build with the production deploy credential in reach. The boundary between untrusted contribution and trusted build is in the wrong place: a secret-bearing job must not execute proposed changes.

open as a page

Your web app's admin console shares a hostname and session with the public site - how do you model it?

level: middleimportance: should knowfreq 62%

basics

~20 s

Model the privileged routes as their own surface, with a boundary drawn inside the process and crossed where a handler decides a session may act with elevated rights. Elevation of privilege dominates the result, and record-changing flows add repudiation.

open as a page

A multi-tenant API also ingests through a queue worker — how do you model where the tenant filter is enforced?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Model every process that reaches tenant-owned data, not just the HTTP handlers, and label each inbound flow with where its tenant identity comes from. A worker that reads the organization id from the message body is trusting caller-influenced data.

open as a page

Field-provisioned solar inverters accept firmware and config over the air — how do you model that update path as an entry point?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Model the update channel as an inbound flow crossing into the device, so the question is what the device verifies before accepting, not just how you authenticate it. A shared installer credential and a fleet-wide push make one compromise reach every unit at once.

open as a page

A support vendor's chat and session-replay script runs on your logged-in pages — what data actually leaves your boundary?

level: seniorimportance: should knowfreq 45%

basics

~10 s

Whatever the authenticated page contains: form fields, tokens in the DOM, personal data, anything typed. Script you include in your page runs with your page's privileges, so the vendor receives flows you never designed.

open as a page

In an event-driven cloud workload, why is a queue message an untrusted entry point?

level: seniorimportance: should knowfreq 51%

basics

~20 s

Whoever the queue's access policy permits to send can invoke the consumer with a payload of their choosing. The trigger binding is the only access control on that path, so an event source is an entry point like any public endpoint.

open as a page

How do you model a cluster add-on that holds full control-plane privilege?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Model it as a component that sits inside every namespace boundary at once, not behind one. Its compromise does not cross boundaries, it erases them, so the threats worth listing are the ones that reach the component: its operators, and the tenant-writable input it acts on.

open as a page

Your production release gate is a chat button hitting a webhook that records no approver identity. What threats does that create?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Repudiation above all: nothing binds a person to the release, so after a bad deploy nobody can establish who authorized it. Spoofing follows, because the webhook authenticates a call rather than an approver, and elevation of privilege if knowing the URL is enough to trigger a deploy.

open as a page

One API service exposes public, partner and internal tiers — how do you threat-model it and where do you invest?

level: principalimportance: should knowfreq 38%

basics

~20 s

Treat one deployment as three surfaces with three attacker populations, credential types and reachable operations, and model each separately. Unlisted internal endpoints on a shared listener are reachable, and a stolen machine credential is silent, long-lived and partner-wide.

open as a page

Every step of a data-export workflow shares one execution role. How do you rate and fix that?

level: principalimportance: should knowfreq 36%

basics

~20 s

Rate it by the union of everything the shared role can reach, not by how harmless each step looks: a compromise in the least significant step inherits the most sensitive grant. Fix it with per-step roles and a narrower handoff payload.

open as a page

How do you threat-model a support agent's 'view as this member' impersonation route in a customer portal?

level: seniorimportance: nice to knowfreq 32%

basics

~20 s

Treat it as a permanently open, authorized crossing from the operator zone into every member's account. Prevention is off the table without deleting the feature, so the model turns on scoping the capability and recording both identities on every action.

open as a page

Stadium turnstiles must validate season passes offline at kickoff — how do you model a decision the server cannot make?

level: principalimportance: nice to knowfreq 36%

basics

~20 s

Accept that authorization happens on hardware you do not own and model the cost instead of denying it: stale revocation, duplicated passes, no global uniqueness check. Convert prevention into bounded loss plus reconciliation, and decide deliberately which way the gate fails.

open as a page

Your logistics partner's webhook is trusted on a shared secret you cannot change — how do you model and bound a compromised partner?

level: principalimportance: nice to knowfreq 33%

basics

~20 s

Put the secret in the attacker's hands and re-read the diagram. A shared secret and an address allowlist authenticate a channel, not the truth of what it asserts, so treat partner events as claims and bound their financial damage.

open as a page

When is a separate cluster, not a namespace, the only honest trust boundary between two tenants?

level: principalimportance: nice to knowfreq 33%

basics

~20 s

Split when the tenants' threat models differ by more than the cluster can enforce: one tenant runs code nobody reviewed, the assets sit at very different values, or a shared control plane compromise is unacceptable. Otherwise separate node pools usually buy more than a second cluster.

open as a page

Your deploy job also applies schema migrations to the production ledger. How would you argue that design must change?

level: principalimportance: nice to knowfreq 27%

basics

~20 s

Argue it as blast radius, not as taste. Letting the deploy job apply migrations means one merged file executes arbitrary statements against financial records with the pipeline's identity, reviewed by people who think they are approving code. Frame the choice as which authorities the deploy identity should hold.

open as a page