Security architecture and threat modelling
The expensive security problems are rarely exotic. They are a tenancy decision taken in week three, an identifier that turned out to be guessable, a queue that nobody realized crossed a trust boundary — choices made quickly by people who had no reason to think they were making a security decision at all.
The short version: the cheapest time to fix a security problem is before it is built
A design change costs a conversation. The same change after launch costs a migration, a maintenance window, a customer notice and an argument about priority. This engagement moves the decision earlier, and where the system is already running it at least makes the remaining risk explicit and owned instead of assumed away.
There are two halves. The first is an architecture review: reading the system as it is specified and as it actually runs. The second is facilitated threat modelling: a working session in which your engineers enumerate what an attacker would do, and what currently stops them.
What does an architecture review actually look at?
Four things, in this order, because each one constrains the next.
Trust boundaries
Every place a request crosses from something you control into something you do not, or from one privilege level into another: the browser, the API edge, the job queue, the third-party webhook, the model endpoint, the reporting replica. Boundaries that exist in the diagram but not in the code are a recurring finding.
Data flows
Where regulated or commercially sensitive data enters, where it comes to rest, and every copy made on the way — caches, search indexes, exports, logs, analytics pipelines, backups, and the developer laptop that holds a restored snapshot. A data flow map is usually the artifact the client did not have and immediately reuses elsewhere.
Tenancy
How one customer is kept out of another customer’s data: shared schema with a discriminator column, schema per tenant, database per tenant, or something that started as one and drifted into another. The question is not which model is best but where the model is enforced, and what happens on the code path that forgets to enforce it.
The authentication and authorization model
Who the caller is, what the system believes they may do, and where that decision is made. Authentication is usually bought and usually fine. Authorization is usually hand-written, spread across the codebase, and the place where the interesting findings are.
Multi-tenant isolation — where it usually goes wrong
Isolation enforced in application code is isolation that holds only on the code paths someone remembered. The pattern that fails is a query builder that applies the tenant filter in a shared helper, plus eleven places that construct a query without it — a report, an export, an admin screen, a migration script, a cron job.
The recommendation that follows is usually to push the decision down a layer, so that forgetting is not an option: database row-level security bound to a session variable, a per-request context that cannot be omitted, and an immutable audit log written where the application cannot rewrite it. That is engineering ground this practice works on directly — multi-tenant application design, row-level security policies, append-only event logging — which is why the recommendations arrive as things your team can implement rather than as principles.
Facilitated threat modelling, with your engineers in the room
The session works best with the engineers who will implement the changes in the room, together with whoever owns the product decisions and, where the data is regulated, whoever answers for it. Threat modelling done to a team produces a document. Threat modelling done with a team produces a team that can do it again.
The form is chosen to fit the system. STRIDE — spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege — works well when the system decomposes cleanly into components and flows, because it gives a checklist per element and keeps the session moving. Attack trees work better when there is one asset that obviously matters and the question is how many ways there are to reach it: the payout path, the evidence store, the signing key.
Sessions are run remotely, in blocks short enough that people stay sharp, against a diagram that is corrected live as the engineers say what is actually deployed. The corrected diagram is itself a deliverable.
Mitigations mapped to backlog items, not to a generic list
A recommendation that reads “implement least privilege” cannot be scheduled, assigned or closed. Every threat that survives the session is written as a change to a named component, with the control it adds, an owner, a rough size, and the dependency that has to land first. It is written so it can be pasted into your tracker without being rewritten.
Findings are ranked by what an attacker gains against what the change costs, not by a severity label applied in isolation. A medium-severity flaw that takes an afternoon is ahead of a high-severity one that needs a quarter, and the register says so explicitly rather than leaving you to prioritize a flat list.
A repeatable template, so the next feature does not need us
The last deliverable is the one that ends the engagement: a short, in-house template your team runs on its own for the next feature — the questions to ask, the diagram conventions, the point in the design process where it happens, and the bar for what counts as answered. Most teams do not need a standing advisor for this. They need the first one done properly and a pattern to copy.
What you receive
| Deliverable | What it is for |
|---|---|
| Review memo | What the system is, what it holds, what was examined and what was not |
| Trust-boundary and data-flow diagrams | Corrected against what is deployed; reusable in customer security reviews |
| Prioritized design-change register | One row per change, with the threat it answers, an owner and a size |
| Threat modelling template | So your team runs the next one without us |
| Re-review after changes | Confirms the change landed and did not move the problem somewhere else |
Every item is written for a reader who was not in the room: a customer’s security reviewer, an insurer, or the engineer who inherits the system two years from now.
When is the right time to buy this?
Four situations account for most of the work. A new platform where the shape is still negotiable. A re-platform, where the old system’s assumptions are about to be carried across without being re-examined. A customer security questionnaire that exposed architecture gaps and produced questions nobody could answer in writing. And technical diligence ahead of a funding round, where an acquirer or investor will ask how the system holds.
A system that is already running is the ordinary case, and the review is done against the design and the running configuration together, because the two diverge and the divergence is usually where the findings are.
Related work: secure development and code review takes the same findings into the codebase and the pipeline, cloud security configuration review covers the platform the design runs on, and penetration testing checks the build rather than the design. Where the system has a model in it, see AI threat modelling.
How the work is bounded
The scope is agreed in writing before work starts, and the engagement is quoted in writing with it.
SecHB does not issue certifications, attestations or audit opinions: those come from accredited certification bodies, CPA firms and QSAs. The work here is what an organization does to be ready for them.
Nothing here is legal advice. Where a question turns on the law, the work is done alongside the client’s counsel, not instead of them.
Questions we are asked
Do you need access to our code?
An architecture review runs on documentation, a walkthrough with the engineers who built the system, and read access to configuration where it exists — source code is welcome but not required. A design review that never reads an implementation will miss the gap between the two, so where source is available it is read selectively — the authorization layer, the tenancy enforcement, the boundary handlers — rather than end to end.
Who should attend the threat modelling session?
Four to eight people is the workable range. Larger sessions turn into presentations; smaller ones miss the person who knows why the queue was introduced.
How is this different from a penetration test?
Threat modelling asks what could go wrong in the design; a penetration test asks what is wrong in the build. One finds a control that was never specified, the other finds a flaw that is reachable today. They answer different questions and the results do not substitute for each other. A worked example of the output is in what a threat model looks like.
Can you do this for a system that is already live?
Yes, and most of this work is. The register then separates changes that can ship in the current architecture from those that need a migration, so nothing is blocked behind a rewrite that is not going to happen this year.
Put the design decisions in writing before something forces you to
Describe the system, what it holds and who it is exposed to. The reply says what a review and modelling session would cover, what you would receive, and what is out of scope — see also all security services.