Detection and response guide

Detection rules as code, not vendor rules

Most organisations should not start here. If you run a single vendor's stack, have nobody whose job includes detection quality, and have not yet measured which of your existing rules produce findings, writing custom detections adds a maintenance liability to an unmeasured system. Detection as code is what you adopt once tuning has become continuous work, because at that point the rules are already software and the only question is whether you manage them like it.

When is writing your own detections not worth it?

When nobody owns the outcome. A rule in version control still needs somebody to notice when its log source stops arriving, when a field is renamed by a platform upgrade, or when its alerts have been closed benign for four months. Without a named owner, custom detections decay faster than vendor ones, because at least the vendor keeps updating theirs.

It is also poor value when your estate is small and homogeneous. A managed endpoint product with a well-tuned default set, watched by people who understand the business, will outperform a home-grown library maintained in spare time. The threshold is not company size but variety: unusual applications, self-hosted services, custom cloud architecture and industry-specific fraud patterns are the things vendors cannot write rules for, and they are the actual case for doing it yourself.

The honest sequence is to measure first. Rank existing rules by alerts per confirmed finding, fix or remove the worst, and see what is left uncovered. The gaps that remain after that exercise are a short, specific list, and writing five detections you can defend beats importing five hundred you cannot.

What does a detection look like when it is code?

It is a file with the logic and, more importantly, the reasoning. A usable rule file records the hypothesis in one sentence, the technique it maps to in a public framework such as MITRE ATT&CK, the exact log source and fields required, the expected alert volume when healthy, known benign causes, the response the analyst should take, and an owner. The query is the smallest part and the only part most teams write down.

The metadata is what makes review possible. A pull request containing only a query can be reviewed for syntax; a pull request stating the hypothesis and the expected volume can be reviewed for whether the detection is worth having, which is the review that matters. It also makes deletion possible later, since the next engineer can tell what the rule was for without archaeology.

For portability, a vendor-neutral format such as Sigma lets one rule be translated to several query languages, and public rule repositories from platform vendors are worth reading for structure even if you never use their content. The limitation to understand before committing to translation is field mapping: a Sigma rule converts cleanly only if your data has a defined schema, so if your logs are not normalised the conversion produces syntactically valid queries that match nothing.

What goes in the pipeline?

The same stages you would apply to application code, with two additions that are specific to detections: a volume check against real data before deployment, and a post-deployment test that the rule actually fires when the technique is performed.

StageWhat runsWhat it prevents
Pre-commit and lintSchema validation of the rule file, required metadata fields present, references resolveRules with no owner, no data source declared and no stated hypothesis
Unit testThe query matched against fixture events that should fire and events that should notLogic errors and copy-paste rules that match on a field your logs never populate
Volume testThe query run over a window of production history in a non-alerting modeDeploying a rule that will generate thousands of alerts on its first night
DeployAutomated push to the platform, with the rule identifier tied to the commitConsole edits that exist nowhere in review history and vanish at migration
Emulation testThe technique safely performed in a controlled environment, checking the rule firesSilent failure, where a rule looks healthy because it has never been exercised
Scheduled revalidationThe emulation test repeated on a cadence, plus a check that the log source still arrivesSlow breakage from field renames, agent upgrades and dropped feeds

How do you test a detection properly?

By performing the behaviour, not by matching a sample. A unit test against fixture logs proves the query parses your data correctly and nothing more. The question that matters is whether, when someone dumps credentials on a real host in your build of your operating system with your endpoint configuration, an alert appears with enough context to act on. Those two tests fail independently and both are needed.

Open-source emulation projects cover a large share of common techniques with small, documented, reversible actions, and there are equivalents aimed specifically at cloud control plane behaviour. Run them in a controlled environment, from a known host, with the security team informed, and record which detections fired, which fired late, and which produced an alert too thin to triage. The third outcome is the most common and the least discussed.

Keep the results as a coverage record with honest gaps. A matrix that says what you can see, what you can see only with luck, and what you cannot see at all is more useful to a board than a coverage percentage, and far harder to challenge. It is also the artefact that makes the case for the next log source, because the gap is demonstrated rather than asserted.

How does this work in a container estate?

It fits better here than anywhere else, because the platform is already defined in code. Runtime security rules, the Kubernetes API server audit policy, network policies and admission controls are all text files, so putting detections beside them in the same repository with the same review process is a small step and removes an entire class of drift between clusters.

Two specifics matter. First, container detections must key on stable identity, so write rules against image digest, workload name, namespace and service account rather than container name or ID, otherwise both the alerting and the exclusions break on every restart. Second, exec into a production pod and process drift, meaning execution of a binary that was not in the image, are the two highest value detections available in this environment and both are cheap to express as rules.

The artefact that rots is the exception list. Every cluster accumulates rule exceptions for the monitoring agent, the service mesh sidecar, the backup job and the one legacy workload that writes where it should not. In code, each exception gets an owner, a reason and an expiry date, and a scheduled review removes those that no longer apply. Left in a console, the same list becomes a permanent hole nobody can account for.

What does a first version look like in a week?

Take three detections you already run and have opinions about, write them as files with the full metadata, put them in a repository, and add a test that runs the query against a handful of fixture events. That is a day of work and it establishes the shape of everything that follows. Resist starting with a framework decision.

Then add the volume test, because it is the stage that pays for itself immediately. Running a candidate query over the last thirty days of history before it can alert converts the worst failure in this discipline, deploying a rule that floods the queue overnight, into a number seen in a pull request. It requires no new tooling beyond a scheduled query and somewhere to record the result.

Finish the week by running one emulation test against one of the three rules and writing down what happened. If the rule fired with usable context, you have a working loop that can be extended a rule at a time. If it did not fire, you have learned something more valuable than any additional rule you could have written, and you learned it on a Tuesday rather than during an incident.

Common questions

What is detection as code?
Managing detection rules the way software is managed: each rule lives in a file in version control, carries metadata stating its hypothesis, required log source, expected volume and owner, is reviewed by pull request, tested automatically, and deployed by pipeline rather than edited in a console. The point is not the tooling but the reviewability, since a rule with a stated purpose can be assessed, improved and safely deleted later.
Should you write custom detection rules or use vendor rules?
Use vendor rules until you can show what they miss. Custom detections are worth the maintenance when your estate has variety a vendor cannot anticipate, such as self-hosted applications, unusual cloud architecture or industry-specific abuse patterns, and when someone owns detection quality as part of their job. Without a named owner, custom rules decay faster than vendor ones, because the vendor at least keeps updating theirs.
What belongs in a detection rule file besides the query?
The hypothesis in one sentence, the technique it maps to in a public framework such as MITRE ATT&CK, the exact log source and fields it depends on, expected alert volume when healthy, known benign causes, the response an analyst should take, and an owner. This metadata is what makes review meaningful, because a reviewer can then judge whether the detection is worth having rather than only whether the syntax is valid.
How do you test that a detection rule works?
Two independent tests. A unit test runs the query against fixture events that should and should not match, proving the logic and field mapping are right. An emulation test performs the actual technique safely in a controlled environment and checks that an alert appears with enough context to triage. Open-source emulation projects cover many common endpoint and cloud techniques with small reversible actions suited to this purpose.
Does Sigma let you write a rule once and run it anywhere?
Partly. Sigma is a vendor-neutral rule format with converters that translate to several query languages, which removes a lot of duplicated work. The constraint is field mapping: conversion only produces working queries if your log data follows a defined schema that the mapping describes. With unnormalised logs, translation yields syntactically valid queries that match nothing, which is a failure mode that looks like success.
Where do detection rules fit in a Kubernetes estate?
Alongside the rest of the platform definition, since runtime security rules, the API server audit policy, network policies and admission configuration are already files. Two rules earn their place quickly: exec into a production pod, and process drift, meaning a binary executing that was not present in the image. Write both against image digest, workload name and namespace, because container names and IDs change on every restart.

More on Threat detection and response

Let’s create something out of this world together.

Have a project in mind? Contact us for expert design and development solutions. Let’s discuss how we can help grow your business.

Azaadi Offer

Claim a free security assessment

Until 31 August we're covering the cost of a full vulnerability assessment and penetration test. Mention it in your message and we'll scope it with you.

  • Web application testing, authenticated and unauthenticated
  • Mobile application testing across iOS and Android
  • External network and infrastructure assessment
  • Manual exploitation by engineers, not scanner output

Testing and the report are free. Fixing what we find is quoted separately, with no obligation to accept.

Read the full offer

Tell us what you are trying to build and we will tell you plainly whether we are the right people for it. Book a call with an expert to work through the detail, or ask for a fixed quote if the scope is already clear. No obligation either way.

Four fields is all we need to get started.

Fastnexa Logo

© 2026 fastnexa. All rights reserved.