Note

Complexity should earn its place

How I use threat models, explicit residual risk and reversibility to decide which safeguards belong.

I like simple systems, but simplicity is not the same as deleting checks. It means making every layer answer for itself. A validation path might still need strict URL parsing, timeouts, response-size limits and decoding limits. That does not automatically mean it needs a custom network-policy subsystem too.

The useful question is not whether another safeguard is possible. It is which actor we are defending against, what that actor can already do and what failure would cost. An authenticated internal tool and a public endpoint open to anonymous input do not have the same threat model. Treating them as if they do produces code that is harder to understand without necessarily reducing meaningful risk.

When I remove a layer, I want the residual risk named. That turns simplification into an engineering decision rather than optimism. The remaining controls should be easy to point at, and the trade-off should be reversible if the boundary changes.

I want enough structure to make failure predictable, but no machinery that exists only to look thorough. I treat complexity as a recurring cost, paid every time the system changes. If a layer cannot name the risk it reduces, it does not belong.

Back to notes