Security

Security by Design

Foundational

Security comes from how a system is built, not from a layer added at the end. Security added late — a scanner in the pipeline, a WAF in front, a pen test before launch — catches only a small part of what secure design prevents from the first line of code. Assume an attacker will study every feature more closely than any of your users.

Designing for security means you assume the request is hostile, the network is watched, the dependency is compromised, and the insider is curious — and you still keep the system safe. That assumption shapes the architecture, not just the code. The cheapest place to remove a vulnerability is the design stage. The most expensive is a breach notice to a regulator.

For a regulated AML platform, the stakes are real. One design flaw — an unsigned webhook, a missing tenant filter, a forgeable identity claim — can let the wrong person through KYC, expose biometric data, or destroy the evidence trail we are legally required to keep. Build as if our licence depends on it, because it does.

Principles to design against

Building it in

Trusting a client-supplied tenant var tenantId = request.Headers["X-Tenant-Id"];
var customers = db.Query("... WHERE TenantId = @t", new { t = tenantId });

Any caller can set the header to another tenant's id and read their data. The tenant must come from the validated token, on the server, never from a header the caller controls.

Take identity and tenant from the token var tenantId = User.GetTenantId(); // from validated claims
var customers = db.Query("... WHERE TenantId = @t", new { t = tenantId });

The boundary decides who you are. Everything inside trusts that decision and nothing else.

Self-review checklist

Why it matters: A vulnerability found in design costs minutes. The same flaw found in production after a breach costs customers, fines, and trust — and in a regulated AML business, possibly the licence to operate. Security built in is nearly free. Security added on later is expensive, partial, and late.