What Is a Security Review, and When Should It Happen in the Architecture Process?
A complete, beginner-to-production guide to security reviews: what they are, why “bolted-on” security fails, where reviews fit across the architecture lifecycle, how real companies like Netflix, Amazon, Google, and Uber run them, and how to build the habit into your own team — explained from first principles with analogies, Java examples, and production patterns.
From Perimeter Firewalls To Shifting Left
A security review is a structured, repeatable examination of a system’s design, code, configuration, or operational practices, carried out specifically to find weaknesses that could be exploited by an attacker — before those weaknesses ship to production.
A security review is a structured examination of a system’s design, code, configuration, or operational practices, carried out specifically to find weaknesses that could be exploited by an attacker — before those weaknesses ship to production. It is not a single tool, not a single meeting, and not a single person’s job. It is a repeatable process that gets applied at defined checkpoints across the life of a system: when it is first designed, when it changes significantly, and on a recurring schedule even when nothing seems to have changed.
The idea did not begin in software. Militaries have run “red team” exercises — deliberately trying to break your own plans — for centuries. Banks have used dual-control and audit processes for just as long: one person proposes a transaction, another independently checks it before money moves. Civil engineers have independent structural reviews before a bridge is approved for construction. Security review in software architecture is the same instinct applied to systems that move data instead of money or people: before you trust a design with real user data, have someone whose job is to think like an attacker look at it first.
In software specifically, the practice matured in stages. In the 1990s and early 2000s, security was mostly a perimeter problem — firewalls, network segmentation, and “keep the bad guys outside the building.” As applications moved onto the web and became directly reachable by anyone with a browser, that perimeter model broke down; attackers did not need to breach a wall, they could talk directly to your application. This gave rise to application security (AppSec) as a discipline: code review for vulnerabilities like SQL injection, structured methodologies like Microsoft’s Security Development Lifecycle (SDL, formalised around 2004), and the OWASP project, which began cataloguing the most common and dangerous web application flaws.
The more recent shift — and the one most relevant to this article — is the move from “security review as a gate at the end” to “security review as a habit woven through the architecture process.” This is often called “shifting left”: moving security activities earlier in the timeline (to the left, if you draw the project timeline left to right), so that flaws are caught in a design diagram instead of in a production incident. DevSecOps, threat modelling frameworks like STRIDE, and automated pipeline scanning are all expressions of that same shift.
Think of a security review the way you would think of a home inspection before buying a house. You do not wait until you have moved in and the roof is leaking to check whether the roof is sound. A good inspector checks the foundation, wiring, and plumbing before you sign — not because they expect every house to be flawed, but because fixing a foundation crack before you own the house is cheap, and fixing it after you have moved your family in is expensive, disruptive, and sometimes too late.
Pre-1990s — audit & red team tradition
Militaries, banks, and civil engineers have run independent adversarial reviews for centuries. Security review in software borrows this instinct directly.
1990s — perimeter security era
Firewalls and network segmentation are the primary defence. “Inside the network” is treated as safe.
Early 2000s — AppSec is born
Web apps put applications directly on the internet, breaking the perimeter model. Structured code review for SQL injection, XSS and friends becomes essential.
2004 — Microsoft SDL & OWASP
Microsoft formalises the Security Development Lifecycle. The OWASP project catalogues the most dangerous web flaws in what becomes the OWASP Top 10.
2010s — DevSecOps & shifting left
Security activities move earlier: threat modelling at design time, SAST/SCA in CI, secret scanning on every commit. The gate becomes a continuous conversation.
Now — zero trust & continuous review
Perimeter trust is abandoned. Every service verifies every caller. Reviews recur on a cadence, even when nothing visibly changed.
Cost Asymmetry Is Why This Discipline Exists
Software systems fail in an asymmetric way when it comes to security: a single missed check can undo the value of a thousand things the team got right — and the cost of catching that miss grows exponentially the later it is caught.
Why does this discipline exist at all? Because software systems fail in a very particular, asymmetric way when it comes to security: a single missed check, one unvalidated input, or one overly generous permission can undo the value of a thousand things the team got right. A system can have excellent performance, beautiful code, and a flawless deployment pipeline, and still leak every customer’s personal data because one endpoint forgot to check whether the caller was allowed to see that data.
The core motivation for security review is cost asymmetry across time. This is one of the best-supported findings in software engineering research: a flaw caught during design costs a fraction of what the same flaw costs once it is deployed. During design, fixing a flawed trust boundary is a conversation and a diagram edit. In production, the same flaw might mean a customer data breach, regulatory fines, forensic investigation, incident response staffing, customer notification obligations, and reputational damage that outlives the technical fix by years.
Security flaws found late are not just “more expensive to fix” — they are categorically different problems. A code-level bug is a maintenance cost. A production security breach is a trust, legal, and business-continuity event.
Why “we’ll add security later” does not work
Teams under deadline pressure often treat security as a feature that can be bolted on after the “real” functionality is built. This fails for a structural reason: many of the most serious vulnerabilities are not missing features, they are architectural decisions made early and baked into everything built on top of them. Examples:
Trust boundaries
If a system was designed assuming “anything inside our network is trusted,” retrofitting zero-trust principles later means touching almost every service.
Authentication model
Switching from session cookies to token-based auth after 40 microservices have been built against the old model is a multi-quarter migration, not a patch.
Data classification
If sensitive fields were never tagged as sensitive, encryption-at-rest and access logging have to be retrofitted field-by-field across every database and every service that touches them.
These are architectural choices, and architectural choices are exactly what security review is designed to examine — while they are still choices, not yet concrete.
What happens without security review
Systems built without any structured review still often “work” in the functional sense — they pass their tests, they demo well, they ship on time. The absence of security review does not show up as a build failure. It shows up much later, often as: an external researcher reporting a vulnerability, a penetration test finding something the team is embarrassed did not get caught internally, or — worst case — an actual incident where the finding is made by an attacker instead of a reviewer.
The Vocabulary Every Reviewer Runs On
People use “security review,” “threat modeling,” “penetration test,” and “security audit” almost interchangeably — but they are different activities with different goals, different timing, and different people involved.
| Term | What it is | Who does it | When |
|---|---|---|---|
| Security review | Structured examination of a design, code change, or configuration for security weaknesses | Security engineer, senior architect, or trained peer | At defined checkpoints — design, major changes, pre-release |
| Threat modelling | Systematic enumeration of what could go wrong (“what can an attacker do here?”) for a specific system or feature | Architects + security engineers, often with the feature team | During design, before implementation begins |
| Code review (security-focused) | Line-by-line inspection of a specific code change for vulnerabilities | Peer engineers, sometimes with security tooling | Every pull request, continuously |
| Penetration test (“pentest”) | Authorised, hands-on attempt to break into a running system, simulating a real attacker | Internal red team or external specialist firm | Periodically, and before major launches |
| Security audit | Formal, often compliance-driven assessment against a standard (SOC 2, ISO 27001, PCI-DSS) | Certified auditors, often external | Annually or per compliance cycle |
This article focuses primarily on security review in the architecture sense — the practice of examining a system’s design and its evolution for security weaknesses — while touching on how it connects to threat modelling, code review, and testing, since in practice these activities feed into each other.
The CIA triad
Almost every security review, no matter how informal, is implicitly checking a system against three properties, known as the CIA triad:
Confidentiality
Only authorised parties can read the data. A reviewer asks: “Who can see this, and should they be able to?”
Integrity
Data cannot be modified by unauthorised parties, and changes are detectable. A reviewer asks: “Who can write or alter this, and how would we know if they should not have?”
Availability
The system keeps working for legitimate users, even under attack (e.g., denial-of-service). A reviewer asks: “What happens if someone floods this endpoint?”
Imagine a shared class notebook. Confidentiality means only your study group can read the notes (not the whole school). Integrity means only the person whose turn it is can edit today’s page, and everyone can see the edit history. Availability means the notebook is not locked away right before the exam because someone spilled coffee on it (or, digitally, because someone crashed the shared drive).
Trust boundaries
A trust boundary is any point where data or a request crosses from one zone of trust into another — for example, from the public internet into your API gateway, from an authenticated user session into a backend service, or from your application into a third-party payment processor. Security reviews spend a disproportionate amount of time at trust boundaries, because that is where validation, authentication, and authorisation decisions must happen. A flaw inside a trust boundary (e.g., a bug in an internal calculation) is usually far less dangerous than a flaw at a trust boundary (e.g., a missing authorisation check on a public endpoint).
Threat modelling with STRIDE
STRIDE is a widely used mnemonic, originally developed at Microsoft, for the categories of threats a reviewer should look for at each trust boundary:
| Letter | Threat category | Violates | Example question |
|---|---|---|---|
| S | Spoofing | Authentication | Can someone pretend to be another user or service? |
| T | Tampering | Integrity | Can someone modify data in transit or at rest without detection? |
| R | Repudiation | Non-repudiation | Can someone deny having performed an action, due to missing logs? |
| I | Information disclosure | Confidentiality | Can data be exposed to someone who should not see it? |
| D | Denial of service | Availability | Can someone make the system unusable for legitimate users? |
| E | Elevation of privilege | Authorisation | Can a low-privilege user gain admin-level access? |
When reviewing the design of a new “export my data” feature, a reviewer applying STRIDE might ask: Spoofing — is the export request tied to a verified session? Tampering — can the export job ID be guessed or altered to export someone else’s data? Information disclosure — does the exported file include fields the user should not see (like internal risk scores)? Denial of service — can a user trigger thousands of exports and overload the system? Elevation of privilege — does the export service run with more database permissions than it needs?
The Review Process Is A System, Not A Meeting
A mature security review process is a small system of its own — defined roles, defined artefacts, defined checkpoints, and a defined loop that feeds production findings back into the next design.
Roles involved
Security architect / security engineer
Owns the review process, brings deep knowledge of attack techniques, and often maintains the organisation’s threat model library and secure-design standards.
Software / solution architect
Brings deep knowledge of the system being reviewed; responsible for incorporating findings into the design.
Feature / product engineers
Implement the system; participate in reviews as the people who best know the code-level details.
Security champion
A common pattern in larger orgs: one engineer per team, trained in secure design basics, acting as the first point of contact for security questions and triaging when a full security team review is needed.
Compliance / risk officer
In regulated industries, ensures reviews also check against regulatory obligations (e.g., data residency, PCI-DSS scope).
Artefacts a review process produces
| Artefact | Purpose |
|---|---|
| Architecture / design doc with a “Security” section | Forces the designer to state trust boundaries, data classification, and auth model up front. |
| Threat model diagram (data-flow diagram + STRIDE annotations) | Visual map of trust boundaries and identified threats. |
| Risk register | Tracks each identified risk, its severity, owner, and remediation status. |
| Review sign-off / approval record | Auditable evidence that a review happened and what was decided. |
| Security requirements checklist | Standard checklist (auth, input validation, encryption, logging) applied consistently across teams. |
Where the review process sits relative to the SDLC
Notice the loop at the end: production is not the finish line. Systems evolve, new threats emerge, and dependencies get new vulnerabilities disclosed against them — so the review process feeds back into design on a recurring cadence, not just once. This is why we draw the diagram as a cycle, not a straight line: every arrow that returns upstream represents a real, budgeted activity in a healthy program, not an aspiration.
How A Security Review Actually Happens
Zooming into a single review session, here is the mechanical process a reviewer typically follows, whether it is a 30-minute lightweight check or a multi-day deep review of a critical system.
Establish scope and context
The reviewer first understands what is being reviewed: is this a brand-new system, a significant change to an existing one, or a routine periodic check? Scope also means understanding what data the system touches — public data, internal data, or regulated data like health records or payment card numbers — because the depth of review scales with data sensitivity.
Build or update the data-flow / trust-boundary diagram
The reviewer (often together with the architect) draws or updates a diagram showing every component, every place data crosses between components, and which of those crossings represent a trust boundary. This is the single most valuable artefact in the whole process, because most serious vulnerabilities are found by staring at trust boundaries, not by reading code line-by-line.
Apply a threat modelling framework (e.g., STRIDE)
At each trust boundary, the reviewer systematically asks the STRIDE questions from Section 3. This is deliberately mechanical — the value of a framework is that it stops the reviewer from only thinking about the threats they happen to remember, and forces coverage of categories they might otherwise skip.
Check against known-vulnerability categories
The reviewer cross-references the design or code against a maintained list of common flaw categories — the most widely used reference is the OWASP Top 10, a regularly updated list of the most critical web application security risks (things like broken access control, injection flaws, and security misconfiguration).
Rate and prioritise findings
Not every finding is equally urgent. Reviewers typically rate findings by a combination of likelihood (how easy is this to exploit, and how likely is someone to try) and impact (what is the worst realistic outcome).
Document, assign, and track to closure
Findings go into a risk register with an owner and a deadline. A review that produces findings nobody is responsible for fixing is, in practice, no better than not reviewing at all — the tracking step is what turns a review from a conversation into an actual risk reduction.
A common severity scale
| Severity | Meaning | Typical response |
|---|---|---|
| Critical | Directly exploitable, high impact (e.g., unauthenticated access to all user data) | Blocks release until fixed |
| High | Exploitable with some effort, or high impact but harder to trigger | Must be fixed before release, or within days if already live |
| Medium | Requires specific conditions; limited impact | Scheduled fix, tracked with a deadline |
| Low | Best-practice deviation with minimal realistic impact | Backlog item |
A simplified Java example · enforcing authorisation at a trust boundary
A very common finding in real reviews is “the endpoint checks that the user is logged in, but not that the user is allowed to access this specific resource” — known as a broken object-level authorisation flaw. Here is the kind of before/after a review typically produces:
// BEFORE — flagged in review: authentication checked, authorisation missing
@GetMapping("/invoices/{invoiceId}")
public Invoice getInvoice(@PathVariable Long invoiceId, Authentication auth) {
// Any logged-in user can fetch ANY invoice by guessing the ID
return invoiceRepository.findById(invoiceId)
.orElseThrow(() -> new NotFoundException("Invoice not found"));
}
// AFTER — fix applied following review finding
@GetMapping("/invoices/{invoiceId}")
public Invoice getInvoice(@PathVariable Long invoiceId, Authentication auth) {
String currentUserId = auth.getName();
Invoice invoice = invoiceRepository.findById(invoiceId)
.orElseThrow(() -> new NotFoundException("Invoice not found"));
// Authorisation check: does this invoice actually belong to the caller?
if (!invoice.getOwnerId().equals(currentUserId)) {
// Log as a security-relevant event, not just a normal 404
securityAuditLog.record("UNAUTHORIZED_INVOICE_ACCESS_ATTEMPT",
currentUserId, invoiceId);
throw new AccessDeniedException("Not authorised for this invoice");
}
return invoice;
}This exact class of bug — “authenticated but not authorised” — is consistently one of the most commonly found issues in real-world security reviews and is called out explicitly as the top risk category in OWASP’s most recent Top 10 list, precisely because it is easy to miss when a team is focused on “does the user have to log in” rather than “does this specific user own this specific resource.”
Where Reviews Fit In The Architecture Process
This is the question in the article’s title, and it deserves a direct answer: a security review should happen at every point where a meaningful architectural decision is made or a system’s attack surface changes — not only once, right before launch.
Checkpoint 1 · During design (highest leverage point)
This is the most valuable moment for a review, because the cost of change is lowest. At this stage, a reviewer is looking at diagrams and documents, not code — checking the trust boundaries, the authentication and authorisation model, data classification, and third-party dependencies before a single line is written.
Checkpoint 2 · During implementation (continuous)
As code is written, security-relevant changes get reviewed continuously through pull request review, ideally supported by automated tooling: SAST (static application security testing, which scans source code for known-bad patterns), SCA (software composition analysis, which checks third-party dependencies for known vulnerabilities), and secret-scanning (catching accidentally committed credentials).
Checkpoint 3 · Pre-release (gate)
Before a system — or a significant new feature in an existing system — goes live, a focused review confirms that all findings from earlier stages are resolved or explicitly accepted as a known, tracked risk, and that dynamic testing (DAST, and for high-risk systems, a penetration test) has been performed against a running instance.
Checkpoint 4 · Post-deployment, on a recurring cadence
Threats do not stay still. A design that was safe last year may not be safe today because: a new vulnerability class was discovered, a dependency the system relies on was found to have a flaw, the system’s data sensitivity changed (e.g., it now stores something regulated), or the system’s exposure changed (e.g., it became internet-facing after previously being internal-only). This is why mature organisations schedule periodic reviews — commonly annual for stable systems, more frequent for high-risk ones — independent of whether a change was requested.
Checkpoint 5 · Triggered by significant change
Beyond the schedule, certain events should always trigger an unscheduled review: a new trust boundary is introduced (e.g., adding a third-party integration), the system starts handling a new category of sensitive data, authentication/authorisation logic changes, or the system’s network exposure changes (internal-only to internet-facing).
Imagine building a treehouse. You would check the tree’s health and the ladder design before building (design-stage review). You would check each plank as you nail it in (continuous review). You would do a final wiggle-test before letting kids climb up (pre-release gate). And every spring, you would check again for rot, even if nobody touched it over winter (periodic review) — because wood degrades even when nobody changed it, the same way software dependencies quietly develop new known vulnerabilities over time.
Depth vs. Velocity, Solved By Risk-Tiering
Security review is not free — it takes time, slows some decisions, and requires expertise that is often scarce. A fair treatment of the topic has to acknowledge the real costs, not just the benefits.
Benefits
- Catches flaws when they are cheapest to fix (design stage).
- Creates institutional memory via threat models and risk registers.
- Builds a shared, explicit understanding of trust boundaries across teams.
- Reduces the chance of regulatory and reputational damage.
- Improves engineers’ security intuition over time (a review is also a teaching moment).
Costs & risks
- Adds calendar time to design and release cycles.
- Requires scarce specialist expertise, which can become a bottleneck.
- Can become “rubber-stamp” theatre if not staffed or empowered properly.
- Risk of over-indexing on checklist compliance instead of real threat thinking.
- Poorly scoped reviews can slow low-risk changes as much as high-risk ones.
The core trade-off · thoroughness vs. velocity
Every organisation has to decide how much review depth to apply to how much change. Reviewing every single pull request with a full threat-modelling session is not sustainable at scale — most changes are low-risk (a UI copy change, an internal logging tweak). The common resolution is risk-tiering: classify changes by risk (e.g., based on whether they touch authentication, payment data, or add a new trust boundary) and apply proportional review depth — lightweight automated checks for low-risk changes, full human review for high-risk ones.
| Risk tier | Example change | Review depth |
|---|---|---|
| Low | UI text change, internal-only logging tweak | Automated scans only |
| Medium | New internal API endpoint, non-sensitive data model change | Peer review + automated scans |
| High | New authentication flow, new third-party integration, new PII field | Full security team review + threat model |
| Critical | Payment processing, new public-facing system, regulated data | Full review + external penetration test before launch |
Large engineering organisations commonly formalise this tiering so that most day-to-day changes flow through automated pipeline checks (fast, no human bottleneck), while a small percentage of higher-risk changes are routed to a security team for deeper, human-led review — keeping the scarce expert time focused where it has the most leverage.
A Review Process That Cannot Scale Gets Bypassed
It might seem odd to talk about “performance” and “scalability” for a review process rather than a running system — but a review process that cannot scale with the organisation becomes a bottleneck, and teams start routing around it, which defeats its purpose.
Why manual-only review does not scale
If every code change requires a human security expert’s sign-off, the security team’s headcount becomes a hard ceiling on how fast the entire engineering organisation can ship. This is the same bottleneck pattern seen in any system with a single non-scalable resource — the fix is the same too: parallelise and automate what can be automated, and reserve scarce expert time for what genuinely needs judgment.
Scaling techniques
Automation in the pipeline
SAST, SCA, secret scanning, and infrastructure-as-code scanning run automatically on every commit, catching a large share of known issue patterns without waiting on a human.
Security champions network
Training one engineer per team to handle first-line triage means most questions never need to reach the central security team at all.
Self-service threat modelling
Standardised templates and checklists let architects run a baseline threat model themselves, escalating to the security team only for high-risk or unusual designs.
Golden paths / paved roads
Pre-approved, pre-reviewed building blocks (an approved authentication library, an approved API gateway configuration) mean teams that use them inherit security review that was already done once, instead of repeating it per team.
Risk-tiering
As covered in Section 7, matching review depth to risk level so low-risk changes are not gated by scarce expert time.
This mirrors how large codebases scale code quality: not every line is manually reviewed by a principal engineer — linters and automated tests catch the bulk of routine issues, freeing up senior review time for architecturally significant changes. Security review scales the same way: automation for the routine, humans for the judgment calls.
Denial Of Service Is A Security Threat, Not Just Ops
Security review connects directly to availability, because denial-of-service is a security threat, not just an operations concern — the “A” in the CIA triad. A system that is functionally correct but falls over the moment someone sends malformed or excessive traffic has a security gap, even if no data was ever exposed.
What reviewers check for reliability-under-attack
Rate limiting
Is there a limit on how many requests a single client can make, to prevent resource exhaustion?
Input size limits
Can an attacker send an oversized payload to exhaust memory or CPU (e.g., a “zip bomb” or deeply nested JSON)?
Graceful degradation
If a downstream dependency is overwhelmed, does the system fail safely (reject new requests, show a friendly error) or does it fail catastrophically (crash, cascade the failure to other services)?
Circuit breakers
Does the system stop hammering a failing downstream service, preventing a small failure from becoming a system-wide outage?
Redundancy and failover
For critical systems, is there a tested failover path if a primary instance or region becomes unavailable — whether due to an outage or a targeted attack?
Imagine a single toll booth on a bridge. If ten thousand cars show up at once, even perfectly law-abiding traffic can create a jam that blocks emergency vehicles. A well-designed system needs a plan for “too many requests,” the same way a bridge needs a plan for “too much traffic” — whether that surge is innocent (a product launch going viral) or malicious (a deliberate flood attack).
Where this connects back to review
A design-stage security review is exactly where a reviewer asks: “What is the failure mode if this endpoint gets 100x its expected traffic?” and “Does a failure in Service B take down Service A, or does A degrade gracefully?” These questions are cheap to answer with a diagram and expensive to answer for the first time during an actual incident.
The Core Controls Every Review Actually Checks
This section goes one level deeper into the specific technical controls a thorough security review evaluates, beyond the high-level STRIDE framing already covered.
Authentication
Reviewers verify: passwords (if used) are hashed with a modern, slow hashing algorithm (like bcrypt or Argon2) rather than a fast general-purpose hash; multi-factor authentication is available for sensitive accounts; session tokens are generated with a cryptographically secure random source and expire appropriately; and there is protection against brute-force login attempts (lockouts or rate limiting).
Authorisation
As shown in the Java example in Section 5, authorisation must be checked per-resource, not just per-endpoint. Reviewers also check for the principle of least privilege — does each service, user role, and API key have only the permissions it actually needs, and nothing more?
Input validation and injection defence
Reviewers check that all external input — from users, from other services, from third parties — is validated and, where it is used to build queries or commands, handled through mechanisms that prevent injection.
// BEFORE — vulnerable to SQL injection, flagged in review
public List<User> searchUsers(String name) {
String sql = "SELECT * FROM users WHERE name = '" + name + "'";
return jdbcTemplate.query(sql, userRowMapper);
}
// AFTER — parameterised query, safe from injection
public List<User> searchUsers(String name) {
String sql = "SELECT * FROM users WHERE name = ?";
return jdbcTemplate.query(sql, userRowMapper, name);
}Data protection · encryption in transit and at rest
Reviewers check that sensitive data is encrypted in transit (TLS, with modern cipher suites and no fallback to deprecated protocols) and at rest (database-level or field-level encryption for sensitive fields, with keys managed through a proper key management service rather than hardcoded in config files).
Secrets management
API keys, database passwords, and encryption keys should never live in source code or plain configuration files. Reviewers check that secrets are pulled from a dedicated secrets manager at runtime, with access tightly scoped and rotated periodically.
Logging and audit trails (addressing “Repudiation” from STRIDE)
Security-relevant actions — logins, permission changes, data exports, failed authorisation attempts — need to be logged in a tamper-evident way, so that “who did what, when” can always be reconstructed. Note: logs must never contain the sensitive data itself (passwords, full card numbers) — logging the wrong thing is itself a security finding.
Dependency and supply-chain risk
A huge share of real-world vulnerabilities come not from code a team wrote, but from third-party libraries. Reviewers check that dependencies are tracked, scanned for known vulnerabilities (via SCA tooling), and kept reasonably current — plus that the build pipeline itself is protected against tampering (a supply-chain attack).
Large-scale breaches are very often traced back not to some exotic zero-day, but to one of the items above being missed: an unpatched known vulnerability in a dependency, a missing per-resource authorisation check, or credentials left in a place they should not have been. This is precisely why review checklists exist — to make sure the well-understood, common causes of breaches get checked every time, rather than relying on individual memory.
Measuring The Review Process Itself
A mature organisation does not just run reviews — it measures whether the review process itself is working. This section covers what to monitor, both for the systems being reviewed and for the review process as a program.
Metrics for the systems under review
- Time-to-detect: how long between a vulnerability being introduced and it being found (ideally: during design/code review, not months later in production).
- Time-to-remediate: how long between a finding being logged and it being fixed, tracked per severity tier.
- Number of findings by severity, over time: a declining trend suggests earlier stages (secure defaults, training) are working; a rising trend suggests a process gap.
- Escaped defects: vulnerabilities found in production that should have been caught earlier; each one is worth a “how did our process miss this?” retrospective.
Metrics for the review process as a program
- Review coverage: percentage of high-risk changes that actually went through the appropriate review tier, versus what was supposed to happen per the risk-tiering policy.
- Review turnaround time: how long teams wait for a review, which is the leading indicator of whether the process will be bypassed under deadline pressure.
- Findings recurrence: the same category of finding appearing repeatedly across teams suggests a training gap or missing “golden path” tooling, not just individual mistakes.
Mature security programs often track these as dashboards visible to engineering leadership, not just the security team — because review turnaround time and coverage are leading indicators of whether the process is actually being followed under deadline pressure, versus quietly skipped when it becomes inconvenient.
Logging design specifically for security observability
Beyond application logs, security-focused monitoring typically includes: authentication event logs (successful and failed logins, from where), authorisation failure logs (attempts to access resources without permission — often the earliest signal of an attack in progress), and anomaly detection on access patterns (e.g., a service account suddenly reading far more records than its historical baseline).
Most Cloud Breaches Are Configuration, Not Code
Modern systems are deployed to cloud infrastructure, and cloud environments introduce their own review surface — misconfiguration, not code vulnerabilities, is one of the most common root causes of cloud data exposure.
Infrastructure-as-code (IaC) review
Since infrastructure is now defined in code (Terraform, CloudFormation, Kubernetes manifests), it should be reviewed the same way application code is — ideally with automated scanning that checks for common misconfigurations before the infrastructure is ever provisioned: overly permissive storage bucket policies, security groups open to the entire internet on sensitive ports, or missing encryption settings.
The shared responsibility model
Cloud providers secure the underlying infrastructure (physical data centres, hypervisor, network fabric); customers are responsible for securing what they build on top of it — their application code, their data, their access configuration, and their identity and access management (IAM) policies. A very large share of cloud security incidents happen entirely within the customer’s side of this boundary — most commonly, an overly permissive IAM policy or a publicly exposed storage resource that was never meant to be public.
What a deployment-stage review checks
Least privilege IAM roles
A service can only access exactly the resources it needs — nothing more, and definitely no wildcard permissions.
Private-by-default storage
Buckets and databases default to private, with explicit, reviewed exceptions for anything that must be public.
Network segmentation
Production and non-production environments are isolated, and internal services are not unnecessarily reachable from the public internet.
Deploy-time secrets injection
Secrets are injected at deploy time from a secrets manager, never baked into container images or checked into git.
Container image scanning
Container images are scanned for known vulnerabilities before deployment, and images with critical CVEs are blocked at the registry.
This kind of diagram is exactly what a design-stage review starts from: it makes the trust boundary between the public zone and the private zone explicit, and every arrow crossing that boundary is a place the reviewer will ask “what stops an attacker from going around this control?”
The Data Layer Is Its Own Review Surface
Data infrastructure has its own review checklist, because it is both a high-value target and a common source of accidental exposure.
Databases
- Encryption at rest: is the database volume encrypted, and are especially sensitive fields (SSNs, payment data, health records) encrypted at the field level with separately managed keys?
- Access control: does every service or user connecting to the database use its own credentials with scoped permissions, rather than everyone sharing a single “admin” database user?
- Backups: are backups encrypted and access-controlled as strictly as the primary database? A common finding is a tightly secured production database with a backup sitting in a loosely secured storage bucket.
- Replication: when data is replicated to read replicas for scaling, does the same access control and encryption policy travel with it, or does the replica accidentally become a weaker copy of the same sensitive data?
Caching
Caches are a frequently overlooked review target because they are treated as “just performance infrastructure.” But a cache holding sensitive data (like a user profile or session token) needs the same confidentiality controls as the database it is caching — plus its own specific risks: cache poisoning (an attacker tricking the system into caching malicious or incorrect data) and cache key collisions (accidentally serving User A’s cached data to User B because the cache key was not scoped precisely enough per user).
Load balancers and API gateways
These sit directly at a trust boundary — the first point of contact between the public internet and the system — so they get particular review attention: is TLS terminated correctly with modern configurations, is a Web Application Firewall (WAF) in place to filter known attack patterns, and is rate limiting applied before traffic reaches backend services (protecting availability, per Section 9)?
Think of a cache like a sticky-note copy of a locked filing cabinet’s contents, kept on your desk for quick access. If the filing cabinet is locked but the sticky note is left in plain view on the desk, the lock did not actually protect anything — the copy needs the same protection as the original.
Every Service Call Is A Trust Boundary
Microservice architectures multiply the number of trust boundaries in a system — every service-to-service call is a potential boundary — which means they also multiply the surface a security review needs to cover.
API-level checks
- Schema validation: does the API reject requests that do not match the expected shape, rather than passing malformed input deeper into the system?
- Versioning and deprecation: are old, potentially less-secure API versions properly retired, rather than left running indefinitely as a forgotten attack surface?
- Rate limiting per client: distinct from general rate limiting, is there a limit tied to each API consumer’s identity, preventing one misbehaving or compromised client from affecting everyone?
Service-to-service authentication
In a microservices architecture, it is tempting to assume “if the call is coming from inside our network, it is trusted” — this is exactly the outdated perimeter-security assumption discussed in Section 1. Modern designs instead use mutual TLS (mTLS) or service-identity tokens so that every service verifies the identity of every other service it talks to, regardless of network location — an approach often summarised as zero trust.
Fan-out and cascading exposure
When one service calls several others to fulfil a request (a fan-out pattern), a review needs to check that a single overly broad permission at the entry point does not implicitly grant access to everything downstream. Each service in the chain should independently verify authorisation for its own piece of data, rather than blindly trusting that “the request already got past the gateway, so it must be fine.”
// Example: each downstream service independently validates
// the caller's authorisation, rather than trusting the gateway alone
@GetMapping("/orders/{orderId}/payment-details")
public PaymentDetails getPaymentDetails(
@PathVariable Long orderId,
@RequestHeader("X-Service-Identity") String callingService,
@RequestHeader("X-User-Id") String userId) {
// 1. Verify the calling service itself is an authorised caller (mTLS/service identity)
serviceIdentityValidator.verify(callingService, "payment-service");
// 2. Independently verify the end user still owns this order —
// do NOT assume the gateway already checked this correctly
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new NotFoundException("Order not found"));
if (!order.getUserId().equals(userId)) {
throw new AccessDeniedException("User does not own this order");
}
return paymentService.getMaskedDetails(orderId);
}Distributed tracing (following a single request as it moves across dozens of microservices) is often introduced primarily for debugging performance issues — but security reviewers rely on the same tracing infrastructure to answer “which services touched this sensitive request, and did each one apply the checks it should have?” It is a good example of infrastructure built for one purpose (observability) becoming genuinely useful for another (security review).
Patterns Reviewers Love, And Ones That Sink Programs
A short round-up of the patterns mature review programs converge on, and the anti-patterns that reliably produce reports without producing real security.
Helpful patterns
| Pattern | What it does |
|---|---|
| Secure by default | New resources start locked down (private, minimal permissions); access is explicitly granted, never assumed open. |
| Defence in depth | Multiple independent layers of control (network, application, data) so a single failure does not fully expose the system. |
| Least privilege | Every user, service, and API key gets the minimum access needed, nothing more. |
| Fail closed | When a security check itself fails or errors, the system denies access rather than defaulting to allow. |
| Paved road / golden path | Pre-approved, pre-reviewed libraries and infrastructure templates that teams can adopt to inherit security review “for free.” |
Anti-patterns
| Anti-pattern | Why it is a problem |
|---|---|
| Security as a one-time gate before launch | Catches flaws too late to fix cheaply; encourages last-minute corner-cutting. |
| Security by obscurity | Relying on attackers not knowing how the system works, instead of real controls — obscurity is not a substitute for actual access control. |
| Perimeter-only trust model | Assumes anything “inside the network” is safe, which fails as soon as any internal component is compromised. |
| Checklist theatre | Reviewers tick boxes without genuinely reasoning about the specific system’s threats — passes audits without reducing real risk. |
| Security team as sole gatekeeper for everything | Creates a bottleneck that either slows the whole organisation or gets bypassed under pressure (see Section 8). |
| Fail open | When an authorisation check errors, defaulting to “allow” rather than “deny” — turns a bug into a security hole. |
“Fail open” often creeps in accidentally: a try/catch block around an authorisation check that, on any exception, logs an error and lets the request through “so users are not blocked by a bug.” This quietly converts every future bug in that code path into an authentication bypass. Reviewers specifically look for this pattern.
Habits That Turn Reviews Into Real Risk Reduction
A short, portable checklist for running a review program that stays healthy year-round — and the recurring mistakes that quietly rot even well-intentioned programs.
Best practices
- Make security review a required step, not an optional courtesy — bake it into the same process (design doc template, PR template, release checklist) that engineers already follow, rather than a separate step people forget.
- Use a consistent framework (like STRIDE) for every review, so coverage does not depend on which reviewer happens to remember which threat category.
- Risk-tier your reviews so scarce expert time goes to genuinely high-risk changes (Section 7).
- Track findings to closure — a finding without an owner and a deadline is a suggestion, not a fixed risk.
- Automate what is automatable (SAST, SCA, IaC scanning) so human reviewers focus on judgment calls, not repetitive pattern matching.
- Review the trust boundaries first, not the whole system uniformly — this is where the highest-value findings live.
- Treat findings as a learning signal, not just a compliance record — recurring finding categories point to a training or tooling gap.
- Keep threat models as living documents, updated when the architecture changes, not archived after the first review.
Common mistakes
- Waiting until pre-launch to do the first security review, when the architecture is already locked in.
- Reviewing code but never diagrams — missing the higher-leverage design-level issues in favour of line-by-line code inspection alone.
- No risk-tiering — either reviewing everything with maximum depth (unsustainable) or reviewing nothing consistently (risky).
- Treating a clean pentest report as proof of security — a pentest only tests what testers thought to try, in the time they had; it is a sample, not a guarantee.
- Ignoring third-party and dependency risk — focusing review entirely on code the team wrote, while unpatched dependencies quietly carry known vulnerabilities.
- No feedback loop — findings from production incidents never make it back into the design-review checklist, so the same category of mistake repeats across projects.
How Netflix, Google, Amazon, and Uber Do It
The same continuous, layered pattern shows up across engineering organisations known for taking security seriously — each with a different accent, but the same underlying shape.
Chaos engineering & red teams
Netflix popularised chaos engineering (deliberately injecting failures into production to test resilience) through tools like Chaos Monkey, and applied a similar “assume failure, test for it deliberately” mindset to security through internal red-team exercises that simulate real attackers against its own production environment, rather than relying solely on point-in-time reviews.
BeyondCorp & zero trust
Google’s engineering culture is closely associated with formalising zero trust at scale through its internal BeyondCorp model, which removed the assumption that being “inside the corporate network” implies trust — every request, internal or external, is authenticated and authorised independently, directly reflecting the “perimeter-only trust model” anti-pattern discussed in Section 15.
Structured readiness reviews
Amazon’s internal engineering practices are known for treating operational and security readiness as a formal, structured gate — new services go through structured readiness reviews before launch, covering not just security but the operational dimensions (Sections 8–9) that determine whether a system fails safely under load or attack.
Pipeline-embedded security tooling
As a company managing highly sensitive, real-time location and payment data across a global microservices architecture, Uber’s engineering organisation has publicly discussed investment in automated security tooling embedded directly into its development pipeline — reflecting the “automate what is automatable, reserve humans for judgment calls” scaling pattern from Section 8.
Across all of these organisations, the same core pattern from this article recurs: security review is not one meeting near the end — it is threat modelling at design time, automated scanning during development, structured gates before release, and continuous testing (chaos engineering, red teams, pentests) in production, feeding findings back into the next design cycle.
The Short Version, In One Portable Frame
Fast, opinionated answers to the questions that come up first when a team is starting to adopt security review as a habit — followed by a compact summary and the eight ideas worth carrying away.
Q: Is a security review the same thing as a penetration test?
No. A security review is a broader, ongoing process that includes design analysis and threat modelling, often before any code exists. A penetration test is one specific, hands-on activity within that broader process — an authorised attempt to break into a running system, typically done periodically or before major launches.
Q: Who should be doing security reviews if we do not have a dedicated security team yet?
Start with the architects and senior engineers who already understand the system, paired with a lightweight framework like STRIDE and a checklist based on the OWASP Top 10. It will not be as deep as a specialist review, but it is far better than no structured review at all — and it builds the habit that a dedicated team can later formalise.
Q: How early is “too early” for a security review?
There is not really a “too early.” The highest-leverage review happens at the architecture/design stage, before implementation — reviewing a rough data-flow diagram costs almost nothing and catches the most expensive-to-fix classes of issues.
Q: Does every single change need a full security review?
No — this does not scale, and it is not necessary. Risk-tiering (Section 7) matches review depth to the actual risk of the change, so routine low-risk changes flow through fast, automated checks while high-risk changes get full human review.
Q: What is the single most valuable habit for a team just starting to adopt security review?
Draw the trust boundaries. A simple diagram showing where data crosses from one zone of trust to another, reviewed with STRIDE questions at each crossing, catches a disproportionate share of serious issues relative to the effort involved.
Q: How does security review relate to compliance requirements like SOC 2, ISO 27001, or PCI-DSS?
Compliance frameworks describe outcomes an organisation must demonstrate — such as “access to sensitive data is restricted and logged” — but they rarely prescribe exactly how to achieve them. A well-run security review process is usually the mechanism that produces the evidence auditors ask for: risk registers, sign-off records, and documented threat models. Teams that only think about compliance once a year, right before an audit, tend to scramble to reconstruct evidence after the fact. Teams that run continuous security reviews as described in this article generally find that compliance evidence falls out of their normal process almost for free, because the artefacts covered in Section 4 were being produced all along, rather than assembled retroactively.
Q: What if a review finds a serious issue in a system that is already live and cannot be fixed immediately?
This is where the risk register and severity rating from Section 5 matter most. A critical finding in a live system usually triggers an accelerated fix timeline, sometimes with a temporary compensating control put in place immediately — for example, tightening a firewall rule, disabling a specific feature, or adding extra monitoring — while the underlying architectural fix is developed properly. What a mature process avoids is either extreme: neither ignoring the finding because “it is already live and hard to change,” nor rushing an untested fix into production under panic, which can introduce new problems of its own. The finding gets an owner, a deadline proportional to its severity, and visible tracking until it is fully closed, exactly like any other finding in the process.
Summary
A security review is a structured, repeatable process for finding weaknesses in a system’s design, code, and configuration before an attacker does. It is not a single gate at the end of a project — it belongs at every meaningful checkpoint in the architecture process: at design time (highest leverage), continuously during implementation, as a gate before release, and on a recurring basis in production, because threats and dependencies keep changing even when the system does not. The core toolkit — trust boundaries, the CIA triad, STRIDE threat modelling, risk-tiering, and tracking findings to closure — scales from a single architect doing a lightweight design check to a mature security organisation running automated pipelines and periodic red-team exercises.
Key takeaways
- Security review = structured, repeatable examination of design/code/config for weaknesses — distinct from pentests and audits, though related.
- The earlier a flaw is found, the cheaper it is to fix — design-stage review has the highest leverage.
- Reviews should recur at defined checkpoints: design, implementation, pre-release, and periodically in production — plus whenever a trust boundary or data sensitivity changes.
- Trust boundaries and the CIA triad (confidentiality, integrity, availability) are the backbone of what a reviewer actually checks.
- Frameworks like STRIDE and the OWASP Top 10 make review coverage consistent instead of dependent on one person’s memory.
- Scaling requires automation (SAST/SCA/IaC scanning) and risk-tiering, so scarce expert time is reserved for genuinely high-risk decisions.
- Findings are only valuable if tracked to closure with an owner and deadline — an untracked finding is just a comment.
- Real organisations (Netflix, Google, Amazon, Uber) all embed this as a continuous practice, not a one-time event, using chaos engineering, zero trust, structured readiness gates, and pipeline automation respectively.
Security review is what happens when a team decides to stop trusting its own optimism — and instead invites someone whose job is to think like an attacker to look at every trust boundary, at every stage, on a recurring schedule that never ends.