Threat Modeling and Attack Surface Analysis Questions
Systematically identifying how a system can be attacked and where its exposure lies. Covers structured methodologies (STRIDE, PASTA, DREAD, OCTAVE, attack trees), enumerating and reducing attack surface, mapping trust boundaries and data flows via DFDs, profiling likely threat actors, and prioritizing identified threats by likelihood and impact during design. Includes applying this methodology to specific architectural substrates (cloud-native and serverless, microservices, ML/AI systems, IoT, CI/CD pipelines, cryptographic subsystems) and operationalizing it as a recurring program (SDLC integration, governance, tooling, KPIs). The proactive 'think like an attacker before you build' discipline: distinct from live penetration testing (the adversarial validation of a built system), from runtime detection/monitoring (recognizing an attack already in progress), and from implementing the resulting security controls (a separate design-and-build discipline).
You're assessing threats for a hybrid multi-cloud deployment that runs sensitive workloads on-prem in Kubernetes clusters and burstable services in public cloud. Enumerate cross-boundary threats (network misrouting, identity federation misuse, config drift, secret sprawl) and design a set of network, identity, and process controls that minimize blast radius while preserving necessary cross-environment connectivity.
Sample Answer
Direct answer
A hybrid deployment's real danger is not either environment individually, it is the SEAM between them: the connectivity, identity federation, and configuration that let workloads span on-prem and public cloud are exactly the mechanisms an attacker can abuse to cross from a lower-value environment into a higher-value one. The four cross-boundary threats to enumerate explicitly are network misrouting (traffic crossing the boundary reaching somewhere it shouldn't), identity federation misuse (a federated identity granting more on the other side than intended), configuration drift (the two environments' security posture silently diverging over time), and secret sprawl (the same credential reused across environments, multiplying the blast radius of any one leak). The controls that actually bound this, rather than just describing it, need to work in all three dimensions at once: network controls that constrain WHERE cross-boundary traffic can go, identity controls that constrain WHAT a federated identity can do on the other side, and process controls that keep the two environments' posture from drifting apart silently.
Structured elaboration
Cross-boundary threats
- Network misrouting: the private connectivity linking on-prem and cloud (a dedicated interconnect or a site-to-site VPN) is itself a routing decision, and a misconfigured route table, an overly broad advertised route, or a route leak can expose more of one environment's internal network to the other than intended, letting a workload on one side reach something on the other side that was never meant to be cross-boundary reachable at all.
- Identity federation misuse: when on-prem identity (an on-prem directory service) is federated to grant access to cloud resources, or vice versa, the mapping between an on-prem identity and its cloud-side permissions is a translation layer that can be wrong in either direction, a role mapped too broadly grants more cloud access than the on-prem identity's actual on-prem privilege level would suggest, or a stolen federation token is usable to pivot from whichever side it was issued on to the other, extending the blast radius of a single-side compromise across the boundary.
- Configuration drift: the two environments are provisioned and managed differently in practice, even with the best intentions, because they typically use different tooling (on-prem infrastructure management versus cloud-native Infrastructure-as-Code), different release cadences, and often different teams; over time this produces a security posture that has silently diverged, a hardening control applied on one side after an incident that never gets mirrored on the other, which an attacker who understands the gap can specifically target.
- Secret sprawl: a credential (a database password, an API key, a service-to-service token) originally scoped for use in one environment gets copied to the other for convenience during the burst-to-cloud setup, and from that point on, a leak of that credential ANYWHERE (either environment's logs, either environment's compromised host) grants access on BOTH sides, which is a materially larger blast radius than either environment having its own distinct, independently-scoped credentials.
Network controls
- Explicit, minimal route advertisement across the interconnect, rather than broadly routing entire address ranges: advertise only the specific subnets that genuinely need cross-boundary reachability, and apply route filtering on both ends of the connection so an unexpected or overly broad route cannot silently propagate, directly targeting the network-misrouting threat.
- Segmented subnets on each side dedicated to cross-boundary traffic, rather than allowing any workload in either environment to originate or receive cross-boundary connections by default; workloads that do not need to communicate across the boundary should not be network-reachable across it at all, which bounds how much of each environment is even a candidate for a misrouting-driven exposure.
- Traffic inspection at the boundary itself, since this is the one network chokepoint both environments' traffic necessarily passes through, making it a natural place to apply consistent monitoring and filtering regardless of which side's tooling is otherwise in use, closing part of the configuration-drift gap by having at least this one control be genuinely shared rather than independently maintained on each side.
Identity controls
- Narrowly-scoped, short-lived federated credentials, rather than a broad standing role granted to every federated identity: a workload or user crossing the boundary should receive a credential scoped to exactly the specific cross-boundary action it needs, with a short expiry, so a stolen federation token has both a limited scope and a limited useful lifetime, directly bounding the identity-federation-misuse threat's blast radius even when a specific token is compromised.
- Separate, non-overlapping identity namespaces with an explicit, audited mapping between them, rather than a single flat identity space spanning both environments; the mapping itself (which on-prem identity maps to which cloud-side role, and why) should be reviewed on a defined cadence, since an unreviewed mapping is exactly where privilege creep accumulates unnoticed over time.
- Per-environment secrets management with no cross-environment credential reuse, directly targeting secret sprawl: each environment issues and manages its own credentials for its own resources, and any GENUINE need for a workload to authenticate across the boundary goes through the federated-identity path above (a short-lived, scoped token) rather than a shared static secret copied into both environments' configuration.
Process controls
- A single source of truth for security configuration, applied to both environments even where the underlying tooling differs, so a hardening decision made in response to a finding on one side is tracked as a change that must also be verified (even if implemented differently, given different tooling) on the other side, directly targeting configuration drift rather than assuming parity happens by default.
- Joint incident-response runbooks spanning both environments, since a cross-boundary compromise, by definition, does not stay inside one team's usual operational scope; a runbook that only covers "if this happens on-prem" or "if this happens in the cloud" leaves exactly the cross-boundary scenario this whole threat model is about without a defined response.
- Periodic joint configuration-parity audits, comparing the actual current state (not the intended state) of both environments' security-relevant configuration, specifically to catch drift that accumulated gradually rather than relying on either side's own internal review process to notice a gap that, by its nature, spans both.
Preserving necessary connectivity while minimizing blast radius
The four threats and three control categories above are deliberately NOT "disconnect the two environments," which would defeat the hybrid architecture's purpose; the design goal is that the boundary is narrow, explicit, and monitored, rather than either wide-open or severed. Concretely: only the specific subnets, identities, and secrets that genuinely need to cross the boundary are allowed to, everything else in each environment is simply not reachable from or by the other side at all, which both preserves the legitimate cross-environment functionality (burst capacity, shared services) and means a compromise on one side does not automatically grant broad reach into the other, only into whatever narrow slice was deliberately exposed across the boundary.
Worked example
A concrete trace of how the controls interact to bound a specific cross-boundary compromise attempt, rather than describing them only abstractly: an attacker compromises a workload in the burstable public-cloud environment (a lower-defense-in-depth target than the on-prem environment holding the sensitive workloads, per the scenario's own framing).
- Without the controls above: the compromised cloud workload sits on a broadly-routed network with reachability to on-prem subnets it does not genuinely need (no network segmentation), holds a static database credential that happens to be the same one used by an on-prem service for convenience (secret sprawl), and the federated identity it authenticates with maps to a broader on-prem role than its actual function requires (identity federation misuse). The attacker pivots directly from the compromised cloud workload to on-prem systems using the shared credential, with no additional exploitation needed.
- With the controls above: the compromised cloud workload's network segment has no route to the on-prem subnet holding the sensitive workload (network segmentation directly blocks the pivot attempt at the network layer, before identity or secrets even come into play); even if a route existed, its federated identity is scoped narrowly to the specific cross-boundary action it legitimately performs (a scoped, short-lived token, not a broad standing role), which does not include reaching the sensitive on-prem system at all; and its database credential is entirely distinct from any on-prem credential, so even a full compromise of this workload's local secrets yields nothing usable on the other side of the boundary.
- The joint incident-response runbook means the response team investigating this compromise checks BOTH environments for related activity from the start, rather than the cloud team handling it as a self-contained cloud incident and only later discovering (or never discovering) a related on-prem signal.
Trade-offs and pitfalls
- Narrow network segmentation adds real operational friction for legitimate cross-boundary use cases, and a common failure mode is teams routing around an overly restrictive segmentation policy with an unofficial, unreviewed workaround (a manually opened firewall rule "just for now") that reintroduces exactly the broad exposure the design was meant to prevent; the segmentation policy needs a fast, legitimate path for adding a genuinely new cross-boundary need, or it will get bypassed.
- Short-lived federated credentials require both environments' tooling to actually support token refresh cleanly; retrofitting this onto an older on-prem identity system that was not designed for short-lived tokens can be a genuinely hard integration problem, not just a policy decision, and should be scoped and budgeted as real engineering work rather than assumed to be a configuration toggle.
- Configuration-parity audits comparing two genuinely different tooling stacks are harder than they sound, since "equivalent" security posture does not always mean "identical configuration" when the underlying platforms differ; the audit needs to compare actual security PROPERTIES (is this data encrypted at rest, is this network path actually restricted) rather than naively diffing configuration files that will never match syntactically between an on-prem system and a cloud-native one.
- Treating the interconnect itself as the only boundary to defend misses that identity and secrets can cross without touching the network path at all (a federated credential used from a completely different network location, a secret leaked via a code repository rather than network traffic); the three control categories are deliberately independent for this reason, and a design that only hardens the network misses the other two threats entirely.
Define a 'trust boundary' in the context of threat modeling. Using a cloud-native application that includes mobile clients, an API gateway, the public internet, VPC-based microservices, and an admin console, explain how you would identify trust boundaries, why they matter for STRIDE, and give three concrete mitigations that specifically protect crossing trust boundaries.
Sample Answer
Direct answer
A trust boundary is any point in a system where the level of trust changes, meaning data or a request crosses from one zone of assumed trustworthiness into another and therefore deserves fresh validation rather than being taken on faith from the previous zone. Trust boundaries matter for STRIDE specifically because STRIDE threats concentrate exactly at these crossings: a component that only ever talks to itself has little to spoof, tamper with, or escalate against, while a boundary crossing is where an attacker actually has to prove or fake something.
Structured elaboration
For a cloud-native application with mobile clients, an API gateway, the public internet, VPC-based microservices, and an admin console, identify trust boundaries by walking every data flow in the DFD and asking, at each hop, whether the entity on one side should trust the entity on the other side by default. The boundaries that emerge: (1) between the public internet and the API gateway, the outermost and most obvious boundary, where any anonymous caller is on the far side; (2) between the API gateway and the VPC-based microservices, IF the gateway does authentication and the microservices simply trust a header the gateway sets, since anything with network access to the internal VPC could forge that header unless it is cryptographically bound; (3) between the mobile client and the backend specifically, distinct from the generic "public internet" boundary, because a mobile client's credentials (an API key, a signing secret embedded in the app binary) are extractable by anyone with the app installed, which is a different and weaker trust assumption than a browser session; (4) around the admin console specifically, which should be treated as crossing INTO a higher-trust zone than the rest of the public-facing surface, not just another instance of the internet-to-gateway boundary, because the blast radius of a compromise there is categorically larger.
Why they matter for STRIDE: each of STRIDE's six categories (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) is really a question about what an attacker on the LOW-trust side of a boundary can do to the HIGH-trust side. Spoofing asks whether the high-trust side can be tricked about who is on the low-trust side. Tampering and Information Disclosure ask what the low-trust side can alter or read as data crosses. Repudiation asks whether the crossing leaves enough evidence for the high-trust side to later prove what the low-trust side actually did. Denial of Service asks whether the low-trust side can exhaust the high-trust side's capacity to serve anyone else. Elevation of Privilege asks whether the low-trust side can gain capabilities meant only for the high-trust side. Running STRIDE without first marking boundaries means asking these questions everywhere uniformly, which wastes effort on low-risk internal-to-internal flows and can miss the crossings that actually matter.
Worked example
Three concrete mitigations that specifically protect boundary crossings, one each for three of the four boundaries identified above (the internet-to-gateway boundary is left out here only because it is the one every team already defends by reflex, not because it matters least): (a) at the mobile-client-to-backend boundary, use short-lived, per-session tokens obtained via an authenticated exchange rather than a long-lived API key embedded in the app binary, since the binary-embedded secret is trivially extractable and should never be treated as a real secret once assumed leaked; (b) at the gateway-to-microservices boundary, use a cryptographically verifiable identity (a signed, short-lived internal JWT or mTLS client certificate) rather than a plain forwarded header, so a service receiving a request can verify the gateway actually authenticated the caller rather than trusting an unsigned claim; (c) at the admin-console boundary, require a distinct, stronger authentication factor (hardware-key-backed MFA, not just password-plus-SMS) and network-level isolation (a separate ingress path, not shared with the public API surface), so that compromising the public-facing credential store does not automatically grant admin access.
Trade-offs and pitfalls
The most common mistake is treating "internal network" as a trust boundary's SAFE side by default, rather than an assumption that needs to be actively verified; a lot of real breaches happen precisely because an internal service trusted another internal service's identity without verification, and the attacker who got a foothold anywhere inside then had free rein. A second common mistake is drawing trust boundaries only around network topology (public vs. private subnet) and missing boundaries that exist for other reasons, like the mobile-client-secret-extraction case above, where the network path may be identical to a browser's but the trust assumption is genuinely weaker.
Given this architecture description, identify hidden trust boundary misconfigurations and propose design changes:
- Mobile app (public) communicates with an API Gateway (public L7) → routes to API service running in the same VPC as the database
- API service connects directly to Database on port 5432 with a single shared DB credential
- Admin UI deployed in the same cluster as the API uses the same DB credentials and exposes an admin route on a public load balancer
- CI system can run arbitrary scripts that have network access to the cluster
List at least five issues, explain the associated risks, and propose fixes prioritized by impact and effort.
Sample Answer
Direct answer
The architecture has one structural flaw repeated five different ways: components that should sit on opposite sides of a trust boundary are instead sharing a boundary, most visibly a single shared database credential used by both the API service and the admin UI, and a build system with unrestricted network reach into the same cluster that credential lives in. None of these five issues individually requires an exotic attack; each is a direct consequence of "everything in the same VPC/cluster is treated as equally trusted," which is precisely the assumption a trust-boundary review exists to catch. Fix order should prioritize removing the admin UI's public exposure and splitting the shared database credential first, since both are high impact and comparatively low effort, before the harder network-segmentation and CI-hardening work.
Structured elaboration
Issue 1: Admin UI exposed on a public load balancer
Risk: an administrative interface, by definition capable of higher-privilege actions than the customer-facing API, is reachable directly from the internet with the same exposure as the public mobile-app-facing path. This collapses a trust boundary that should exist between "anyone on the internet" and "an authenticated administrator," turning any vulnerability in the admin UI itself (an authentication bypass, a vulnerable dependency) into a directly internet-exploitable path to administrative access, rather than requiring an attacker to first gain internal network access.
Fix: move the admin UI behind a private network path (a VPN, a bastion, or an internal-only load balancer, plus a separate strong authentication mechanism such as multi-factor authentication) so it is not reachable from the public internet at all. Impact: high (removes a direct internet-to-admin path entirely). Effort: low-to-medium (a load balancer/routing change plus, ideally, adding a stronger auth requirement; does not require restructuring the application itself).
Issue 2: Single shared database credential across API service and admin UI
Risk: because both components authenticate to the database as the same identity, the database cannot distinguish "the customer-facing API doing a normal customer-scoped query" from "the admin UI doing an administrative action," which means (a) neither component's database access can be scoped to only what it actually needs (least privilege is impossible when the credential is shared), (b) a compromise of either component grants the SAME database access as compromising the other, so the admin UI's public exposure (Issue 1) effectively also exposes whatever the API service's database access allows, and (c) there is no way to audit which component performed a given database action, since the credential identity is identical for both.
Fix: issue distinct, narrowly-scoped database credentials per component (the API service gets exactly the customer-data permissions it needs; the admin UI gets its own, separately-scoped and separately-audited credential), ideally via a secrets manager issuing short-lived, per-component credentials rather than static long-lived shared ones. Impact: high (this is the single change that most directly limits blast radius across the whole architecture, since it decouples the two components' compromise consequences from each other). Effort: medium (requires a database-permissions redesign and a secrets-management integration, but does not require re-architecting network topology).
Issue 3: API service and database share the same network segment with no isolation
Risk: the API service connects directly to the database on its default port with no indication of a network-layer boundary (a dedicated database subnet with restrictive security-group rules, a network policy limiting which services can reach the database at all) separating them. This means ANY other workload that ends up running in the same VPC, whether through a future deployment, a compromised unrelated service, or (concretely, per Issue 4) a CI job with cluster network access, can potentially reach the database directly, not just the API service that is supposed to be its only legitimate client.
Fix: place the database in its own subnet with security-group or network-policy rules that allow inbound connections ONLY from the specific API service's network identity, not from the VPC broadly. Impact: high (this is the control that actually enforces "only the API service talks to the database," which the architecture currently only achieves by accident, since nothing structurally prevents another workload from doing the same). Effort: medium (network-policy or security-group changes, testable incrementally, but requires care not to break the legitimate path while restricting everything else).
Issue 4: CI system has arbitrary script execution and network access to the cluster
Risk: this is the most severe issue in the set, because it means the build system, which by design runs code from pull requests, dependency updates, and build scripts, sits INSIDE the same trust boundary as production, with network reachability to everything else described above (the database, given Issue 3's lack of isolation, and potentially the admin UI's cluster-internal path even if Issue 1 is fixed). A single compromised dependency or a malicious pull request effectively grants an attacker the same network position as any other cluster workload, without needing to compromise the API service or admin UI at all.
Fix: run CI build agents in a separate, isolated network with no direct path to production systems; where a CI job genuinely needs to interact with production (a deployment step), route that through a narrowly-scoped, audited deployment mechanism rather than general network reachability, and use ephemeral, least-privilege build agents rather than long-lived ones with broad access. Impact: high (closes what is otherwise a direct path from "arbitrary code an attacker can influence" to "the same network as the database"). Effort: high (typically requires a genuine network-topology redesign separating CI infrastructure from the production cluster, which is more disruptive than the other fixes and needs careful sequencing to avoid breaking legitimate deployment paths).
Issue 5: No stated authentication/authorization boundary between the API Gateway and the API service
Risk: the description states the API Gateway routes to the API service, with no mention of the API service independently verifying that a request actually came through the gateway with proper authentication applied, versus trusting any request that reaches it on the internal network. If the API service implicitly trusts anything that reaches it over the internal network (which Issue 3's lack of network isolation makes broader than intended), then any other workload on that network, again including a compromised CI job, could call the API service directly, bypassing whatever authentication the gateway is supposed to enforce.
Fix: have the API service independently verify a signed assertion of gateway-applied authentication (rather than implicitly trusting all internal traffic), so the internal network position alone is not sufficient to act as an authenticated caller. Impact: medium-to-high (closes a defense-in-depth gap; the specific severity depends on what the gateway's authentication would otherwise be relied on to fully prevent). Effort: medium (requires the API service to add a verification step, generally a contained code change rather than an infrastructure change).
Prioritized order
| Priority | Issue | Impact | Effort |
|---|---|---|---|
| 1 | Admin UI public exposure | High | Low-medium |
| 2 | Shared database credential | High | Medium |
| 3 | CI arbitrary network access to cluster | High | High |
| 4 | No network isolation around the database | High | Medium |
| 5 | Implicit internal trust between gateway and API service | Medium-high | Medium |
Issues 1 and 2 lead because they combine high impact with comparatively achievable effort and can each be fixed largely independently of the others; Issue 4, the CI system's network access, is sequenced third despite being arguably the most severe root cause, specifically because its fix (a genuine network-topology redesign separating CI from production) is the most disruptive, and it benefits from Issues 1-2 already having reduced what a CI-originated compromise could reach in the meantime. Issue 3's database isolation then follows at priority 4, cheaper than the CI redesign but narrower in what it closes on its own.
Worked example
Tracing a single realistic compromise path through the CURRENT architecture, using the issues above, to show them compounding rather than being independent findings:
- An attacker compromises a transitive dependency pulled in during a routine build (a supply-chain attack, not requiring any flaw in the application code itself).
- Because the CI system has network access to the cluster (Issue 4) with no isolation from production, the malicious build step can attempt to reach cluster-internal services directly.
- Because the database has no network-layer isolation restricting it to only the API service (Issue 3), the compromised build step can reach the database directly on port 5432.
- Because the credential is shared between the API service and the admin UI, and effectively usable by anything that can reach the database on the network (Issue 2), the attacker does not need to steal a distinct "admin" credential separately; the one credential in use grants full access regardless of which component it was originally issued for.
- The result: a compromised dependency in a routine build reaches full database access, without ever needing to exploit the mobile app, the API gateway, the API service's application logic, or the admin UI's public exposure at all. This is exactly why Issue 4 (CI network access) is arguably the root cause connecting the others, even though Issues 1 and 2 are fixed first for practical sequencing reasons.
Trade-offs and pitfalls
- Fixing issues in isolation without checking for exactly this kind of compounding path is a common mistake. Each of the five issues looks individually moderate in isolation; the worked example shows why they need to be evaluated as a connected graph, not five independent checklist items, since the actual severity comes from the chain, not any single link.
- "Same VPC" is often mistaken for "trusted network," when it should mean nothing about trust on its own. A VPC boundary is a network-routing construct; treating co-location within it as equivalent to a trust boundary, rather than defining trust boundaries explicitly with their own enforcement (network policies, distinct credentials, distinct authentication), is the single assumption underlying all five issues here.
- Sequencing by effort alone, ignoring impact, risks fixing the cheap issues while leaving the most severe one (CI network access) unaddressed indefinitely because it is always the hardest and therefore always gets deprioritized; the prioritization above deliberately keeps Issue 4 at priority 3, not last, specifically to avoid that trap.
- A partial fix to the shared-credential issue (rotating the credential without actually splitting it into per-component identities) looks like progress but does not change the underlying problem: the database still cannot distinguish which component is acting, so blast radius and auditability are unimproved even though "the password changed."
Consider this architecture: Mobile client -> API Gateway -> Auth Service (JWT) -> User Service -> Orders Service -> PostgreSQL. Orders Service publishes events to RabbitMQ consumed by Fulfillment Service. Admin Console accesses services via VPN. Create a component-level DFD, identify trust boundaries, and perform a STRIDE analysis for key data flows and components. Then list the top five prioritized threats with brief mitigations.
Sample Answer
Direct answer
I would first draw the component-level data flow diagram (DFD, a diagram that shows how data moves between processes, data stores, and external entities) exactly as the architecture is described, mark every point where trust level changes as a trust boundary, then walk each component and each data flow crossing a boundary through STRIDE (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege), Microsoft's threat-categorization framework for systematically asking "what can go wrong here" component by component. That produces a long list of candidate threats; the top five that make the priority list are the ones sitting on the most exposed trust boundaries with the highest blast radius if exploited, which in this architecture means anything touching the JSON Web Token (JWT, a compact signed token format used here to carry the caller's identity between services) and anything touching the admin path, because those are where a single compromise reaches the most of the system.
Structured elaboration
The method: DFD, trust boundaries, then STRIDE per element
Draw the components and data flows as given, mark every point where the level of trust changes as a boundary, then walk each component and each flow crossing a boundary through STRIDE (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege) asking which of those six properties could fail there. That produces a long candidate list; prioritize it by exposure (how reachable the threat is) and blast radius (how much of the system a successful exploit reaches) rather than by STRIDE category alone, since categories are a checklist for finding threats, not a severity ranking. Applying that method to the architecture given in this question is the worked example below.
Worked example
Component-level data flow diagram and trust boundaries
flowchart LR
subgraph TB1["Trust boundary: public internet"]
Mobile["Mobile client"]
Admin["Admin operator"]
end
subgraph TB2["Trust boundary: edge / perimeter"]
GW["API Gateway"]
end
subgraph TB3["Trust boundary: internal service mesh"]
Auth["Auth Service (issues JWT)"]
User["User Service"]
Orders["Orders Service"]
Fulfill["Fulfillment Service"]
MQ[("RabbitMQ")]
end
subgraph TB4["Trust boundary: data plane"]
DB[("PostgreSQL")]
end
Mobile -- "HTTPS request" --> GW
Admin -- "VPN tunnel" --> GW
GW -- "auth request" --> Auth
GW -- "JWT-bearer request" --> User
User -- "JWT-bearer request" --> Orders
Orders -- "SQL over TLS" --> DB
Orders -- "publish event" --> MQ
MQ -- "consume event" --> Fulfill
Four trust boundaries, each a point where the level of trust in the caller changes:
- Public internet to edge: the Mobile client and the Admin operator are both untrusted until authenticated; this is where the API Gateway sits as the enforcement point.
- Edge to internal service mesh: once past the gateway, requests carry a JWT and are treated as authenticated, but the services still need to verify that JWT rather than implicitly trusting anything that reached them.
- Within the service mesh, at the message broker: Orders Service and Fulfillment Service are decoupled through RabbitMQ (a message broker: software that accepts messages from one service and delivers them to subscribed consumers, here over the Advanced Message Queuing Protocol, AMQP). This is still a trust boundary because Fulfillment Service trusts whatever it reads off that queue, and anything that can publish to it can act as Orders Service from Fulfillment's point of view.
- Service mesh to data plane: PostgreSQL (a relational database) is the boundary where application-level authorization decisions have to already be enforced, since the database itself only enforces what its own connection credentials allow. The diagram's "SQL over Transport Layer Security (TLS)" label on that flow is the encryption-in-transit expectation; a database connection that silently fell back to an unencrypted connection would itself be a Tampering and Information disclosure finding worth its own line in the STRIDE table below.
The Admin Console's Virtual Private Network (VPN) tunnel is drawn reaching the API Gateway rather than bypassing it, because "administrative access" is not itself a trust boundary exemption; if the VPN only gates network reachability and the gateway still authenticates and authorizes every admin request the same way it does user requests, the admin path does not get a free pass on the STRIDE analysis below. If the real architecture instead lets VPN-connected admins skip the gateway's checks, that gap is itself one of the top threats (see below).
STRIDE analysis of key components and flows
| Component / flow | STRIDE category | What the threat looks like |
|---|---|---|
| Mobile to API Gateway | Spoofing | An attacker without valid credentials impersonates a legitimate client |
| JWT issued by Auth Service | Spoofing, Tampering | A stolen or forged JWT lets an attacker impersonate any user; a JWT accepted without signature verification lets claims be tampered with |
| Gateway to User/Orders Service | Elevation of privilege | Broken authorization lets a request escalate beyond its token's intended scope (a regular user's token reaching admin-only Orders operations) |
| Orders Service to PostgreSQL | Information disclosure | Compromised or overly broad database credentials expose more customer and order data than the calling service needs |
| Orders Service to RabbitMQ | Tampering | A message altered in transit or by an unauthorized publisher changes what Fulfillment Service acts on |
| RabbitMQ to Fulfillment Service | Spoofing | A rogue publisher on the same queue impersonates Orders Service, triggering fulfillment actions that never happened |
| Admin Console via VPN | Repudiation, Elevation of privilege | Admin actions without individual attribution make it impossible to prove who did what; a VPN-only gate with no additional authorization check gives broad access on network presence alone |
| API Gateway itself | Denial of service | A traffic spike or targeted flood against the single ingress point degrades or takes down the whole system, since every other component sits behind it |
Top five prioritized threats and mitigations
Ranked by a combination of exposure (how reachable the threat is) and blast radius (how much of the system a successful exploit compromises), not by STRIDE category alone:
- JWT theft or forgery (Spoofing). The highest-blast-radius threat: a valid or forged JWT is accepted as proof of identity by every downstream service. Mitigation: short-lived tokens, a rotating signing key managed through a key management service, and binding the token to the client session (for example Demonstrating Proof-of-Possession, DPoP) so a stolen token alone is not sufficient.
- Broken authorization allowing privilege escalation between services (Elevation of privilege). A request that reaches User or Orders Service with a valid but lower-privileged JWT should not be able to reach admin-only operations. Mitigation: enforce authorization as its own explicit check inside each service (not just "the gateway let it through"), using the token's scope claims against each specific operation.
- Tampered or spoofed messages on the Orders-to-Fulfillment path (Tampering, Spoofing). Because RabbitMQ decouples Orders from Fulfillment, a compromised publisher credential can inject fabricated fulfillment events. Mitigation: message-level signing (an HMAC over each message body) so Fulfillment Service verifies authenticity independent of network-level access control, plus scoped publish permissions per service identity.
- Admin path privilege misuse with no attribution (Repudiation, Elevation of privilege). If the VPN is treated as sufficient authorization rather than just network reachability, any compromised admin credential or laptop grants broad, unaudited access. Mitigation: individual admin authentication behind the VPN (not a shared network-level trust), just-in-time elevation for sensitive operations, and immutable audit logging of every admin action.
- Denial of service against the API Gateway (Denial of service). Every request path in this architecture funnels through one ingress component. Mitigation: rate limiting per client, autoscaling the gateway tier, and a web application firewall in front of it to absorb obviously malicious traffic before it reaches application logic.
Trade-offs and pitfalls
- Treating the gateway as the only enforcement point. It is tempting to authenticate once at the edge and let everything behind it trust the request implicitly; the STRIDE table above exists specifically because internal services (User, Orders, Fulfillment) each need their own authorization check, not a shared assumption that "it already passed the gateway."
- Message queues are an easy trust boundary to overlook. A synchronous request/response chain gets threat-modeled almost by habit; an asynchronous publish/consume hop like Orders-to-RabbitMQ-to-Fulfillment is easy to skip because there is no direct caller to authenticate, but the consumer is trusting the message's origin just as much as it would trust a direct caller.
- "It's behind the VPN" is not an authorization answer. Network-level access and identity-level authorization are different controls; conflating them is one of the most common gaps in real architectures that otherwise look well-designed on paper.
- Prioritizing threats by STRIDE category alone, rather than exposure and blast radius, misranks the list. A Repudiation finding and a Spoofing finding on the JWT path are not equally urgent just because they are both "on the list"; this worked example ranks by what an exploit actually reaches, which is why the JWT threat outranks the queue-tampering threat despite both being real findings.
That is every published Threat Modeling and Attack Surface Analysis question for Network Engineer so far. Browse the other topics in this category, or practice this one interactively.