Skip to content

Secure by design: a practical checklist for small teams shipping products

ENISA's 22 secure-by-design playbooks for SMEs: what they ask for, the order to adopt them in, and what changes when a model writes some of the code.

RaadCraft Engineering · · 7 min read · Updated

Abstract diagram: three stages in a row separated by diamond gate markers, with a shield outline at the last gate

Security advice aimed at small teams tends to fail in one of two ways. Either it is a list of principles too abstract to act on, or it is an enterprise framework that assumes a security team you do not have.

ENISA's Secure by Design and Default Playbook, published in July 2026, is unusually well aimed at the gap. It is subtitled a practical guide for SMEs, and it is structured as 22 separate playbooks rather than one document: 14 for secure by design, 8 for secure by default. Each one carries a principle, an objective, a checklist, a minimum-evidence requirement, and release gate criteria.

That last part is what makes it useful, because "minimum evidence" and "release gate" are the words that turn a principle into something you can fail a build on.

What the 22 cover

The secure-by-design set works through architecture and process: trust boundaries and threat modelling, least privilege, strong identity and authentication architecture, attack surface minimisation, defence in depth, open design, life-cycle management, user-centric design, secure coding and verification, logging and monitoring, configuration and change management, incident response and recovery, vulnerability and patch management, and supply-chain controls.

The secure-by-default set is about what your software does before anyone configures it: minimising default services, restrictive initial access, secure communication by default, unique device identity and secrets, mandatory security onboarding, automated maintenance and updates, transparent security posture, and secure recovery and ownership life cycle.

Read straight through, the list is daunting. It gets more manageable once you accept that the 22 are not equally urgent for a team of six.

The order we would adopt them in

If you are shipping a product now and have no formal security process, this is roughly the sequence that buys the most safety per week of effort.

Start with the ones that stop whole categories of incident.

  • Restrictive initial access and secure communication by default. Nothing ships open and gets locked down later. Later does not arrive.
  • Strong identity and authentication architecture. Not just "we added login": session handling, token lifetimes, and what happens on password reset.
  • Least privilege. Every service credential scoped to what that service actually does. This is tedious and it is the single highest-return item here.
  • Supply-chain controls. A lockfile, a dependency audit in CI, and a policy for what happens when it fires.

Next, the ones that make an incident survivable.

  • Logging, monitoring and alerting. You cannot investigate what you did not record. Log auth events and privileged actions specifically.
  • Vulnerability and patch management. A named owner and a stated response window, even if the window is generous.
  • Incident response and recovery. One page. Who is called, what gets shut off, how customers are told.
  • Automated maintenance and updates. Manual patching does not survive a busy quarter.

Last, the ones that keep the first two from decaying.

Trust boundaries and threat modelling, configuration and change management, secure coding and verification, and transparent security posture. These are the practices that stop the earlier work quietly rotting as the team changes.

What changes when a model writes some of it

The playbooks assume a person wrote the code. In most small teams shipping in 2026, a good share of it was not. That does not add items to the list. It changes which ones are urgent.

eu-LISA's technology monitoring report on generative AI in software development, published in July 2026, is a useful companion here, because it splits the security question into three layers, and each one maps onto a playbook already in the list above.

Output is the code itself. A 2021 study of GitHub Copilot found roughly 40% of completions carried a weakness from MITRE's CWE list. Models have improved since, and a 2025 analysis of public repositories is the fairer figure: 87.9% of the AI-generated code it examined showed no identifiable CWE. The eighth that did is still a lot of code, and what kind of weakness it holds matters more than the count. A large 2025 comparison of human-written and AI-written code found the AI side skewed towards particular high-risk weaknesses, command injection and hard-coded secrets among them, and more vulnerable on average than the human code it was measured against. The defects also differ in kind: less structural complexity, more repetition, more variable assignment errors. Your review habits are tuned for a different distribution of mistakes than the one you are now getting.

Two results from the same section deserve more attention than any of those rates. Asking a model to improve its own code did not make it safer, and one controlled experiment measured a 37.6% rise in vulnerabilities after five rounds of refinement prompting. A 2023 study found developers with an assistant wrote less secure code than a control group while being more confident it was secure. The trust is doing most of the damage, because code that looks reviewed rarely gets reviewed.

Input is what leaves your machine. Source code in prompts, repository access granted for context, and telemetry kept for debugging that can include snippets even where training opt-out is configured. You answer this one by reading terms of service, not by changing code, and the answer belongs next to whatever you already promise customers about their data.

Agent is the newest of the three. A coding agent has the file system, a shell, and usually the network. It takes its instructions in natural language, so anything it reads is a possible instruction, and indirect prompt injection becomes something you have to design against. Connecting it to internal systems through MCP servers also dissolves the isolation that used to contain a compromise: one bad server reaches everything the agent reaches.

Small teams have two extra problems at the output layer. The first is tool sprawl. Three developers on three assistants, each backed by a different model with its own reading of the codebase, produce work with inconsistent conventions, which is harder to review and easier to hide a flaw in. The second is that an agent's output tracks the quality of what it can read. eu-LISA is blunt about that: getting value from these tools requires a well-maintained codebase and documentation in machine-readable formats. The README you keep meaning to update is now an input to code that ships.

Four items on the checklist move as a result.

  • Supply-chain controls stop being only about known-vulnerable versions. Models invent package names, and an invented name is one an attacker can register and wait on. Composition analysis that flags a dependency with no upstream package is now a security control.
  • Least privilege extends to the agent. Its credentials, its sandbox, and the set of systems any MCP server it talks to can reach.
  • Secure coding and verification leaves the last group and joins the first. If a model writes a meaningful share of your code, you need review with static analysis, plus a pass aimed at the failure modes the report names: hard-coded secrets, unsafe library use, and unsanitised input.
  • Configuration and change management now covers the tools as well as the software. Which assistants are allowed, which models, what they are permitted to touch, and who reviews their output. eu-LISA files this under cross-cutting measures along with developer training and periodic audits, and for a team of six it can be a page.

This is also why generation speed is a poor thing to measure. The time saved lands in the editor and the time owed lands in review, and only one of those shows up in a demo. Whoever approves the release still owns the security of code they did not write.

Make the gate real

The most valuable idea in the playbook structure is the release gate. A checklist nobody can fail is documentation, not a control.

Pick three or four items you can check automatically and enforce them in CI: dependency audit passes and every dependency resolves to a package that really exists, a secret scanner finds nothing in the diff, TLS and auth configuration matches the expected baseline. Add the rest as a short human checklist on the release ticket, and name the AI failure modes on it so a reviewer is looking for something specific. The point is not comprehensiveness on day one. It is having one thing that can actually block a deploy, so the others have somewhere to attach.

What this does not solve

Secure by design is about the product you build. It says nothing about the laptop it was built on, the contractor with production access, or the invoice email that turns out to be fraudulent. Those are the incidents small companies actually suffer, and they need separate attention.

But the product side is the part you control completely, and it is the part your customers inherit. Twenty-two playbooks is a lot to adopt at once. Four of them, actually enforced at the release gate, is worth more than all 22 in a document nobody opens.