28. Juli 2026

Defence in Depth: Avoid Common Traps When Using Coding Agents

 Deutsche Version 

Coding agents can be useful in day-to-day development, especially when teams need to move quickly across unfamiliar code, repetitive implementation work, or operational tooling. At the same time, they introduce a familiar engineering problem in a new form: the code may look reasonable, pass basic checks, and still violate an important requirement. That is why defence in depth remains relevant when coding agents are part of the development process.

Why this matters

The pace of software delivery has increased. Teams are working with new models, new tools, and new ways to produce features and internal tooling. Coding agents fit naturally into that environment because they can turn instructions into code, tests, or refactorings with very little delay.

What has not changed is the harder part of engineering. Someone still needs to define what the software should do, what it must not do, and what should happen when the system is uncertain. Requirements are often incomplete or slightly inconsistent. In that situation, a coding agent will usually try to make progress by filling in the gaps. Sometimes that is helpful. Sometimes it introduces an assumption that conflicts with the real intent.

This is especially relevant for software that touches live accounts, permissions, or customer data. In those cases, a small misunderstanding in the generated code can become an operational problem.

What defence in depth means here

Defence in depth is a simple idea. A single check should not be the only thing preventing a bad outcome. Instead, several layers should work together so that if one layer is wrong, another one still limits the damage.

Most teams already apply this idea in software delivery. Changes go through review, deployments are validated in pipelines, automation runs with limited permissions, and production access is treated more carefully than development access. None of this is unusual. It is standard engineering practice because it reduces the effect of mistakes.

The same thinking is useful when code is generated with AI support. The question is not whether the agent can produce working code. The question is whether the surrounding process still protects important constraints when the generated code takes a wrong turn.

The first safeguard is still a clear specification

When coding agents are involved, specification becomes more important, not less. If the instructions are vague, the model will still try to complete the task. That often leads to code that is internally consistent but based on assumptions nobody intended to approve.

A useful architectural document does not need to be long, but it should be clear about the objective, the hard rules, the conditions under which processing must stop, and the expected failure behavior. In practice, this is often where the real engineering work still sits. It is also where many risks can be reduced before any code is generated.

This point is easy to overlook because coding agents create the impression that implementation has become the main challenge. In reality, the difficult part often remains the same: defining the problem precisely enough that an implementation can be trusted.

A practical example: synchronizing users across systems

One common integration task is synchronizing user accounts between a central user management system and several connected systems. The central system acts as the source of truth, while downstream platforms need to stay aligned with it over time.

On paper, that sounds routine. In practice, it becomes more sensitive as soon as deletion is part of the workflow. A synchronization tool may identify an account in a downstream system that no longer appears in the central directory and classify it as orphaned. From there, it is tempting to treat deletion as the natural next step.

But an account can be orphaned from the perspective of identity management and still be linked to data that should not be removed. It may own records, files, project state, or other information that still matters. Once that possibility exists, the workflow needs a stricter rule than simple consistency between systems.

The rule in this case is straightforward: a user must not be removed while relevant data is still present.

Where the common trap appears

This is where defence in depth becomes practical rather than theoretical. It is not enough to check once, early in the workflow, whether data exists. That check matters, but it should not be the only protection.

In the case behind this article, the generated implementation eventually delegated account removal to an external command-line tool. That tool supported a parameter that forced deletion even if associated data still existed. The parameter had been included in the script.

At first glance, that choice could look harmless. One possible line of reasoning is that earlier checks had already confirmed that the user was safe to remove, so the extra parameter merely ensured the command completed cleanly. The problem is that this reasoning depends entirely on the upstream logic being correct.

If the classification is wrong, if the data view is stale, or if a bug appears between validation and execution, the forceful delete option removes the last barrier. Without that option, the target system still has a chance to refuse the operation. With it, the workflow becomes less tolerant of mistakes in earlier stages.

That difference is the core of the defence-in-depth argument. The final step should fail safely when the earlier logic turns out to be incomplete.

What this changes in review

When teams review agent-generated code, the important question is often not whether the code works in the expected path. The more useful question is whether the generated implementation preserves the intended safety model.

That requires a slightly different review habit. Instead of looking only at the direct behavior of the function or script, it helps to compare the implementation against the architectural rule it is meant to protect. If the specification says that deletion must never happen when data exists, then every part of the workflow should reinforce that rule rather than quietly weaken it.

This is also why tests, documentation, and review still matter. Over time, refactoring creates dead paths, test suites become noisy, and documentation drifts away from the implementation. Coding agents can accelerate all of that just as easily as they accelerate productive work. The value of defence in depth is that it keeps critical constraints visible across those layers.

Conclusion

Coding agents are useful tools, but they do not remove the need for careful system design. If anything, they make it more important to state hard rules clearly and preserve them across architecture, implementation, testing, and operations.

For synchronization workflows and other forms of operational automation, defence in depth means that no single check should carry the full responsibility for safety. A human review, a clear specification, cautious execution, and a final command that still fails safely all have a role to play. That is not an argument against automation. It is a way to make automation easier to trust.

Call to Action

If your team is introducing coding agents into identity workflows, systems integration, or operational automation, Jaraco can help review the architecture around those processes and identify where practical safeguards are worth adding.

jaraco-software-engineers-verlauf-cta
jaraco-logo

Kontaktieren Sie uns noch heute und lassen Sie uns gemeinsam Ihre Softwarelösungen entwickeln!