DAM Technology Solutions
Journal / Security

Security by Design in everyday engineering practice

6 min read

Security added at the end is a patch. Security designed at the start is an architecture. The difference shows up in the estimate.

Security by Design is easy to put on a slide and harder to point at in a codebase. In practice it is not a phase and not a tool. It is a handful of decisions taken early, each of which is cheap at the time and expensive later.

Roles before screens

The first security artefact on any project is not a scan. It is a table of who can see what and who can do what. Writing it before the interface exists tends to expose questions the business has not settled: whether a manager can view another region's data, whether support can act on behalf of a customer, whether an integration account is allowed to delete anything.

Answer those on paper and access control falls out of the model. Answer them after the fact and permissions become a growing pile of conditional checks scattered across the code.

Secrets have a lifecycle

Credentials are usually treated as a setup step: generate a key, put it in the environment, move on. The interesting questions come later. Who can read that value today, how would you know if it had leaked, and what exactly happens on the day it has to be replaced. A system where rotating a database password means an unplanned outage has a security problem that no scanner will report.

The practical baseline is modest and worth insisting on: no secrets in the repository or in a chat thread, a single place where they live, separate values per environment so a staging leak is not a production incident, and at least one rehearsed rotation before launch. Rotation that has been practised once is an operation. Rotation attempted for the first time during an incident is a second incident.

Log the decisions, not just the errors

Most systems log failures well and successes badly. For anything touching money, health, or contracts, the useful record is the opposite: who approved this, when, and on what basis. An audit trail designed alongside the feature costs very little. Reconstructed afterwards from application logs, it is guesswork.

The same care applies in the other direction. Logs written without thought become their own exposure, because a debugging line added under pressure will happily copy a full request body, tokens and personal data included, into a system with far weaker access rules than the database it came from.

Data you never collect cannot leak

The cheapest control available is deciding not to hold something. Every field a system stores carries a cost that shows up in access rules, backups, exports, support tooling, and eventually in a regulator's questions. A surprising amount of what gets collected was requested because it seemed useful, not because a defined process needs it.

  • Ask what each field is for. If nobody can name the process that reads it, it does not need to be stored.
  • Separate identity from behaviour. Analytics rarely needs to know which person did something, only that the same person did it twice.
  • Give data an expiry. Retention decided at design time is a scheduled job. Decided after five years of accumulation, it is a project.
  • Keep production data in production. Copying a live database into a test environment quietly moves sensitive records into the place with the weakest controls.

Where AI changes the shape of the problem

  • The model is a user. If an assistant can read a knowledge base, it needs its own permissions, not a shared administrative key.
  • Prompts are data. Anything sent to a provider leaves your boundary. Whether it can be retained is a contractual question, decided before integration, not after.
  • Output needs a review path. Where a wrong answer is expensive, the design has to say who checks it and how, or the feature simply moves risk around.
  • Retrieved content is untrusted input. A document pulled into a prompt can contain instructions of its own, so anything the assistant is allowed to act on needs the same scepticism as a form submitted by a stranger.

Dependencies are part of your attack surface

Most of the code shipped in a modern product was written by people the client will never meet. That is a reasonable trade, and it is not free. A dependency is a standing decision to trust a maintainer, a release process, and every package that maintainer in turn depends on, which is why the questions worth asking at the point of adoption are how actively it is maintained, how large its own dependency tree is, and how hard it would be to remove.

Operationally the requirement is to know what you have and to be able to move quickly. A recorded inventory of dependencies, automated alerts on known vulnerabilities, and pinned versions so an upgrade is a deliberate act cover most of it. The remaining part is cultural: upgrades treated as routine maintenance stay small, while upgrades deferred until they are urgent arrive as a migration nobody planned for.

What this looks like in an estimate

Clients sometimes expect a separate security line item. There usually is not one, and that is the point: role design sits inside architecture, audit sits inside the features that need it, secret management sits inside infrastructure setup. What appears instead is a slightly longer design stage, and a shorter, calmer path to launch.

The exceptions are worth naming, because they are real budget: a formal penetration test before go-live, a compliance audit in a regulated sector, and the work of proving controls to a client's own security team. Those are scheduled explicitly. Everything else is simply how the system gets built.

Keep reading All articles