As software engineers and architects, your job isn’t just to build applications that work—it’s to build applications that work securely. In discussions around secure software development, two concepts often come up: secure design principles and threat modeling.
They sound similar. Some use them interchangeably. But they are not the same. In fact, understanding how they differ and how they complement each other is a hallmark of mature security thinking.
Let’s explore how you can apply both effectively in your work.
Secure design principles are like the architectural norms that make a building safe before the doors or windows are even installed. They're universal, technology-agnostic rules that guide how systems should be structured to reduce security risks by design.
Some common principles includes
Principle of Least Privilege: Components should have only the access necessary to perform their functions.
Fail Securely: Systems should default to a secure state in case of failure.
Defense in Depth: Use multiple layers of security controls so that if one fails, others still protect the system.
Keep It Simple (KISS): Complex designs often introduce subtle flaws—simplicity helps reduce errors and vulnerabilities.
Secure Defaults: The default configuration of systems should be secure.
These principles ensure that the system is designed in a way that is resilient, robust, and harder to compromise, even before you consider specific threats.
Threat modeling is a systematic process to identify how your specific application could be attacked, and what you should do to prevent that. It focuses on the real-world adversary, and how they might try to exploit your system.
It answers four key questions:
What are we building?
What could go wrong?
What are we going to do about it?
Did we do a good job?
It typically involves:
Understand what you’re building: Define architecture, components, data flows.
Identify threats: Use frameworks like STRIDE (Spoofing, Tampering, Repudiation, etc.).
Identify mitigations: What will you build or implement to reduce the risk?
Validate: Are the mitigations in place and effective?
Where secure design principles are broad and proactive, threat modeling is specific and reactive to your architecture and use cases.
Let’s say you're designing a multi-tenant SaaS platform with the following features:
User logins
Admin panel
File uploads
API integrations with third-party systems
You ensure:
Users have roles with least privilege
APIs are authenticated
Inputs are validated
File uploads are scanned
Sounds good, right? But what if you miss a very context-specific threat?
What if a malicious tenant uploads a PDF that triggers a server-side request forgery (SSRF) to access internal metadata services in AWS?
Secure design helped lay the groundwork, but you missed a threat specific to your cloud environment and use case. That’s where threat modeling would help.
You brainstorm:
What if the login API is brute-forced?
What if a malicious user escalates privileges?
What if the file upload API is abused?
Great. You start fixing things, adding WAF rules, rate limiting, RBAC. But… what if the underlying architecture violates fundamental design principles?
For example: You gave a shared Redis cache full read/write access across tenants for session management. Now, any vulnerability in one app instance can leak sessions of other customers.
No amount of threat modeling will fix a bad design choice at the core.
Think of it like this:
Secure design principles are like the blueprint rules you follow when building a house—use fire-resistant materials, ensure proper exits, etc.
Threat modeling is like hiring an inspector to check the actual blueprint and say, “Here’s where a burglar could get in, and here’s how to prevent it.”
Both are necessary. You can’t threat model effectively if your design violates basic security principles. And even a perfectly designed system may still need adjustments to address new or evolving threats.
Here’s how to incorporate both into your software lifecycle:
Apply secure design principles first. Think foundationally: How should we structure access, data flows, modules?
Then do threat modeling to examine that structure. Ask: Where are the attackers likely to hit? What’s the worst that could happen?
Implement mitigations discovered from threat modeling.
Follow secure coding standards (input validation, output encoding, logging, etc.)
Validate the threat modeling assumptions through security testing (DAST, SAST, fuzzing, etc.)
Confirm your secure design principles are still upheld in the implementation.
Secure design principles create a secure foundation. Threat modeling adds context-aware, adaptive protection. Together, they enable you to build software that’s resilient, not just compliant.
As developers and architects, you are not just coders—you’re digital defenders shaping the future of secure systems.