๐ก๏ธ Lesson 7: Security Considerations in Design Documents
Building software without security considerations is like building a house with no locks, alarms, or fences. Security isn't an afterthought โ it's a fundamental part of your architecture. The worst time to think about security is after a breach. The best time? Right now, in your SDD.
๐ฏ Learning Objectives
By the end of this lesson, you will be able to:
- Apply the defense-in-depth strategy to your architecture using the castle metaphor
- Use the STRIDE model to systematically identify threats
- Distinguish between authentication and authorization and document both
- Specify encryption requirements for data at rest and in transit
- Reference the OWASP Top 10 when writing security sections of your SDD
- Integrate security testing at every stage of the development pipeline
Estimated Time: 30 minutes
๐ In This Lesson
The Castle Defense Strategy
Medieval castles didn't rely on a single wall โ they used moats, outer walls, inner walls, and a fortified keep. This is defense in depth: multiple layers of security so that if one layer fails, the others still protect you. Your SDD should document each layer and what it defends against.
๐ก The Four Layers in Your SDD
Layer 1 โ Network Security (the Moat): Firewalls, VPNs, network segmentation. Keeps most attackers from even reaching your application.
Layer 2 โ Perimeter (the Outer Wall): WAF (Web Application Firewall), DDoS protection, rate limiting. Filters malicious traffic.
Layer 3 โ Application Security (the Inner Wall): Input validation, authentication, authorization, secure coding practices.
Layer 4 โ Data Encryption (the Keep): The last line of defense. Even if attackers breach everything else, encrypted data is useless without the keys.
The STRIDE Threat Model
STRIDE helps you think like an attacker. It's a systematic checklist: for every component in your architecture, ask "could someone Spoof, Tamper, Repudiate, disclose Information, Deny service, or Elevate privilege?" Then document the mitigation for each threat in your SDD.
โ ๏ธ Threat Modeling Isn't One-and-Done
Run STRIDE every time you add a new component, a new integration, or a new user role. A system that was secure last quarter may have new attack surfaces today. Add a "Security Review Triggers" section to your SDD that lists which changes require a threat model refresh.
Real-World Example: Banking Application Security
Banking systems are the gold standard for security architecture. Notice how this design uses network zones โ each zone has progressively stricter access controls, and no component in the public zone can directly reach the data zone.
Security Architecture for Online Banking
๐ Why Zones Matter
Each zone boundary is a firewall with explicit allow-rules. The DMZ can talk to the Application Zone, but not directly to the Data Zone. The Application Zone can reach the Data Zone, but the Data Zone never initiates outbound connections. This means an attacker who compromises the API Gateway still can't reach the database without also compromising an app server. Document every zone and every allowed connection in your SDD.
Authentication vs Authorization: The Bouncer and the VIP List
These two concepts are frequently confused, but the difference is critical. Authentication (AuthN) answers "who are you?" โ it verifies identity. Authorization (AuthZ) answers "what are you allowed to do?" โ it checks permissions. You need both, and your SDD should document both separately.
๐ก Common Auth Patterns to Document
Authentication: JWT tokens, OAuth 2.0/OpenID Connect, SAML for enterprise SSO, API keys for service-to-service, MFA requirements (which roles? which actions?).
Authorization: RBAC (Role-Based Access Control) for most apps, ABAC (Attribute-Based) when roles aren't granular enough, resource-level permissions (can user X edit document Y?), time-limited access tokens.
๐ซ The "Admin Flag" Anti-Pattern
Don't model authorization as a single is_admin: true/false boolean. Real systems need granular permissions: who can read billing data, who can invite users, who can deploy to production. Start with RBAC and define roles like viewer, editor, billing_admin, super_admin โ with each role's permissions explicitly documented in the SDD.
The OWASP Top 10: Know Your Enemies
The OWASP Top 10 is the industry's most widely referenced list of web application security risks. Your SDD's security section should address how your design mitigates at least the top five:
โ ๏ธ Injection Is Not Just SQL
When developers hear "injection," they think SQL injection. But injection attacks target any interpreter: OS commands, LDAP queries, XPath, template engines, even log files (log injection). The universal defense is: never trust user input. Validate, sanitize, and use parameterized interfaces everywhere โ then document your validation strategy in the SDD.
๐ #4 Is the One That Matters Most for SDDs
"Insecure Design" was added to the OWASP Top 10 in 2021 specifically because security can't be bolted on after the fact. A design that lacks rate limiting, doesn't separate admin and user flows, or stores secrets in config files is insecure by design. This entire lesson is about preventing #4.
Encryption: The Secret Code
Encryption is your last line of defense โ if everything else fails, properly encrypted data is still protected. Your SDD needs to specify encryption for two scenarios: data at rest (stored in databases, file systems, backups) and data in transit (moving between client and server, or between services).
๐ก What to Specify in Your SDD
At rest: AES-256 for database encryption, encrypted backups, key rotation schedule (90 days is common), key management system (AWS KMS, HashiCorp Vault, etc.).
In transit: TLS 1.3 minimum (TLS 1.2 acceptable with strong cipher suites), certificate pinning for mobile apps, mutual TLS (mTLS) for service-to-service communication.
Application-level: Bcrypt or Argon2 for password hashing (never MD5 or SHA-1), field-level encryption for PII (SSN, credit cards), envelope encryption for large datasets.
๐ซ Never Roll Your Own Crypto
This is possibly the most important rule in software security. Use battle-tested libraries (libsodium, OpenSSL, your language's standard crypto library). Even PhD cryptographers get it wrong when implementing from scratch. Document which library you use and which algorithms โ "we use encryption" is not a security specification.
Security Testing in Your Pipeline
Security testing shouldn't be a separate phase that happens after development. It should be woven into every stage of your CI/CD pipeline โ "shift left" means catching vulnerabilities as early as possible, when they're cheapest to fix.
โ What Each Stage Catches
SAST (Static Analysis): Scans source code for vulnerabilities before it runs โ catches SQL injection, hardcoded secrets, insecure patterns. Run on every commit.
Dependency Scan: Checks your package.json/requirements.txt against known vulnerability databases (CVEs). A single outdated library can be the entry point.
DAST (Dynamic Analysis): Tests the running application by sending malicious inputs โ finds XSS, CSRF, auth bypasses that static analysis misses.
Config Scan: Verifies deployment configurations โ open ports, default credentials, overly permissive IAM roles, missing security headers.
Runtime Protection: Monitors production for anomalies โ unusual traffic patterns, failed auth spikes, data exfiltration attempts.
Zero Trust Architecture: Trust No One
Traditional security assumes everything inside the network perimeter is trusted. Zero Trust flips this: nothing is trusted by default, whether it's inside or outside the network. Every request is verified, every connection is encrypted, every access is logged.
๐ Zero Trust in Practice
Zero Trust doesn't mean "don't trust anyone" โ it means "verify before trusting." In practical terms: service-to-service calls use mTLS (not just "they're on the same network"), API tokens have short lifetimes and narrow scopes, internal dashboards require the same authentication as external ones, and every data access is logged for audit.
Security Checklist for Design Documents
๐ Essential Security Sections in Your SDD
Authentication & Authorization: MFA support, RBAC/ABAC model, session management, password policies, token lifetimes, service-to-service auth.
Data Protection: Encryption at rest (algorithm, key management), encryption in transit (TLS version, cipher suites), data classification levels, retention and deletion policies, backup encryption.
Application Security: Input validation strategy, output encoding (XSS prevention), parameterized queries (injection prevention), security headers (CSP, HSTS, X-Frame-Options), dependency management.
Infrastructure Security: Network segmentation and zones, firewall rules, WAF configuration, DDoS protection, secrets management (no secrets in code or config files).
Monitoring & Incident Response: Security event logging (what gets logged, where, how long), alerting thresholds, incident response playbook, breach notification plan, penetration testing schedule.
๐ซ The "Security Through Obscurity" Fallacy
Hiding your API endpoints, using non-standard ports, or obfuscating code is not security โ it's a speed bump that a determined attacker will bypass in minutes. Real security comes from strong authentication, proper encryption, input validation, and defense in depth. If your system's security depends on attackers not knowing how it works, it's not secure.
In the next lesson, we'll explore performance and scalability โ because a secure system that can't handle users is like a fortress with no food. You'll learn to document capacity requirements, caching strategies, database optimization, and scaling patterns.
๐ก Key Takeaway
Security is not a feature โ it's a quality that pervades every architectural decision. Document your threat model, your defense layers, your encryption choices, and your testing pipeline in the SDD. The goal isn't to make your system unhackable (nothing is) โ it's to make attacking it so expensive and slow that attackers move on to easier targets.