Defense in depth
Stacking independent security controls so that when one fails, and one will, the next one still stops the attacker.
See it
What it is
Defense in depth means every control assumes the one in front of it will fail. The login form validates input, and the query is parameterized anyway, and the database role can only read the tables it needs, and row-level security scopes the rows, and the audit log records the read. No single layer is trusted to be perfect, because none of them are. The name comes from military fortification: rings of defenses that slow an attacker down and buy you time to notice.
The practical test is to pick one control and ask 'if this were silently broken today, what would stop the attack?'. If the honest answer is 'nothing', you have a single point of failure wearing a security badge. Classic layers on a web app: edge (WAF, rate limits, bot rules), transport (TLS, HSTS), application (validation, output encoding, authorization checks on every handler), data (least privilege, row-level security, encryption), and detection (logs, alerts, an incident plan for when all of it fails).
The misconception is that layers are interchangeable, so buying a WAF lets you skip fixing the SQL injection. They are not. A layer you added because you could not be bothered to fix the real bug is a delay, not a defense, and attackers get past filters with encoding tricks all day. The other trap is layer sprawl: five overlapping tools nobody has tuned produce so many false positives that the real alert gets ignored.
Ask AI for it
Review this endpoint and harden it with defense in depth, adding controls at every layer rather than one big fix. Edge: rate limit per user and per IP. Transport: enforce HTTPS with HSTS. Application: validate the request body against a strict schema, use parameterized queries, and re-check authorization inside the handler instead of trusting the route guard. Data: run as a database role with only the privileges this feature needs, and add row-level security so a missed check still cannot return another tenant's rows. Detection: log actor, action, and target on every write. For each layer, add a one-line comment saying which failure it is covering for.