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.
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.
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.
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.
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.
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.
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.