Skip to content

Cybersecurity Engineering Handbook / Chapter 66

Detection Specification Template

Turn a threat scenario into a maintained detection claim with dependable evidence, end-to-end tests, accountable response, and visible limits.

At 09:09 UTC, a production alert says that a duplicate export job was accepted. Responders pause the service. Seven minutes later, delayed worker telemetry shows that the worker rejected the duplicate before reading customer data. The query matched its condition, the page reached the right people, and the alert was still wrong about what the system had done.

The incident timeline in the preceding appendix preserves that correction. The detection specification has a different job: prevent the control from making the same semantic mistake again. It must say which system state is dangerous, which observations can establish that state, how quickly a decision is needed, and what the responder may safely do. Query text alone cannot carry that promise.

Detection specification loop showing threat scenario, data source, detection logic, severity, false positives, triage owner, runbook, test method, and known limitations feeding back into the threat scenario.
A detection is maintainable when the threat, signal, logic, owner, runbook, test, and limitations form one review loop.

Specify the decision before the rule

Use a detection specification when creating, changing, tuning, suppressing, or retiring a security detection. Begin with the decision the alert must support. For the export service, a responder must decide whether to pause export work, preserve the job and replay records, and open an incident before a duplicate execution can read or publish customer data.

That decision exposes facts a generic “duplicate accepted” rule hides. API admission and worker execution are different states. A duplicate may be rejected only after it reaches the worker. The response deadline depends on whether the queue can be paused before a read. Delayed worker events cannot be treated as negative evidence. A high-severity page that omits those facts merely transfers unfinished detection design to the on-call responder.

Write both expected and suspicious behavior. Name the entities that join the events and the boundary of the claim. Then state the action and the latest time at which it can still reduce harm. Severity follows plausible impact and urgency; confidence belongs with the evidence.

The reusable specification

Keep the specification beside versioned rule logic and test fixtures, or in a system of record with equivalent review history. Links should resolve to exact versions or durable records rather than dashboard home pages.

# Detection Specification: <stable ID and name>

## Control identity
- Status and rule version: Draft | Observe-only | Active | Suppressed | Retired
- Detection owner and reviewer:
- Triage owner, primary route, and timed escalation route:
- Systems, environments, tenants, and assurance scope:
- Related threat, requirement, control, incident, and replacement detection:
- Review cadence and event-driven review triggers:

## Threat and decision
- Threat or unsafe-failure scenario:
- Expected behavior:
- Suspicious behavior and important variants:
- Deliberately excluded behavior and residual risk:
- Decision the responder must make:
- Decision deadline and harm that grows while waiting:
- Permitted first action, authority, service risk, and reversal condition:

## Evidence contract
### <source or event>
- Producer and data owner:
- Event meaning and lifecycle state represented:
- Required original and normalized fields:
- Entity and correlation identifiers:
- Event clock, ingestion clock, expected delay, and allowed lateness:
- Retention, sampling, redaction, access, and integrity conditions:
- Source-health signal, failure route, and coverage consequence:

## Detection logic
- Plain-language claim:
- Grouping, joins, sequence, window, and allowed lateness:
- Thresholds and boundary behavior:
- Enrichment and its freshness requirement:
- Missing, duplicate, reordered, or conflicting event behavior:
- Severity and confidence context:
- Case evidence and context delivered to the responder:

## Response
- Runbook and first validation step:
- Evidence to preserve before changing state:
- Containment options and required authority:
- Incident, service-owner, privacy, legal, or communication thresholds:
- Closure dispositions and required record:

## Test and release evidence
### <test ID and kind: fixture | replay | simulation | end-to-end>
- Rule and schema version:
- Setup, authorization, safety observer, and stop conditions:
- Expected result and timing:
- Actual result, event IDs, and preserved evidence:
- Coverage proved and coverage not proved:

- Observe-only or activation conditions:
- Rollback condition and procedure:
- Last successful end-to-end test:

## Quality, tuning, and limits
- Expected volume, precision evidence, duplicates, and decision-time target:
- Known benign patterns and how they remain distinguishable:
- Known blind spots, bypasses, source gaps, and compensating controls:
- Active suppression: scope, reason, approver, created, expires, and test:
- Retirement condition, replacement proof, and residual gap:
- Change history: version, reviewer, reason, evidence, and next review:

Not every detection needs many sources or elaborate correlation. A use of a honeytoken may be a single-event, high-confidence signal. The record should be as small as the claim permits, but no smaller than the response decision requires.

Bind the logic to evidence that can support it

For each source, say what its event means in the producer’s lifecycle. A field named decision is inadequate if one producer means “accepted for evaluation” and another means “execution authorized.” Preserve original values during normalization. Enrichment may add owner, criticality, approved change, or tenant context, but its age and failure state must remain visible.

State whose clock supplies event time and how late data may arrive. Define what the rule does with missing fields, duplicate delivery, reordered events, and a failed join. Monitor volume, parsing, required-field completeness, ingestion delay, and reporting coverage. If losing a source invalidates a critical detection claim, that loss needs an independently routed coverage-degraded signal; the broken path cannot be trusted to report its own failure.

A useful plain-language claim is precise enough to challenge before anyone reads the query. It names the entities, state transition, window, exclusions, and outcome represented. The implementation can then be reviewed against that claim instead of being mistaken for it.

Follow the failed export probe into a corrected control

The following record is illustrative. Its identifiers and dates are examples, not production evidence. It continues the export incident so that the change in meaning remains visible.

# Detection Specification: DET-JOB-REPLAY-004 — duplicate export execution

## Control identity
- Status and rule version: Active, version 5
- Detection owner and reviewer: Detection Engineering; Export Security owner
- Triage owner and routes: Security on-call; page Export SRE after 5 minutes
- Scope: production Customer Export Service, all regions and tenants
- Related controls: AUTHZ-TEN-002, JOB-REPLAY-003, LOG-AUD-004
- Review: monthly; also after schema, evaluator, replay, queue, route, or
  containment changes and after any related incident

## Threat and decision
- Scenario: an authenticated actor resubmits an export job and a worker
  executes the duplicate, allowing repeated reads or archive publication.
- Expected behavior: the API may admit the envelope for evaluation; the worker
  must record `rejected_duplicate` before source-data read or archive creation.
- Suspicious behavior: a duplicate reaches final state `execution_authorized`,
  or any source-data read or archive creation follows the duplicate job ID.
- Excluded behavior: misuse of a distinct, valid job by an actor already
  authorized for the tenant. AUTHZ-TEN-002 and export-volume detections cover
  different parts of that risk.
- Decision: whether to pause creation and consumption, preserve the envelope
  and replay state, and declare an incident.
- Deadline: before the next worker read; the queue pause must begin within two
  minutes of a final acceptance or observed read.
- First action: Security on-call may request the documented global queue pause;
  Export SRE executes it. Preserve in-flight job and replay evidence. Reverse
  only with incident-commander and release-owner approval after negative
  production proof.

## Evidence contract
### API admission event `export.job.admitted`
- Meaning: envelope passed API checks and entered evaluation; it is not proof
  of worker authorization or execution.
- Required fields: event_time, ingestion_time, tenant_id, export_id, job_id,
  envelope_digest, admission_decision, request_id, API revision
- Health: 99th-percentile arrival within 60 seconds; page Data Platform if no
  production events arrive for 3 minutes while API traffic is nonzero.

### Worker decision event `export.job.decided`
- Meaning: final replay and authorization decision before source-data access.
- Required fields: event_time, ingestion_time, tenant_id, export_id, job_id,
  envelope_digest, final_decision, replay_record_id, worker_revision
- Health: 99th-percentile arrival within 90 seconds. After that allowance, an
  admitted duplicate with no final decision opens a coverage-degraded case; it
  does not become an accepted execution by inference.

### Object-read and archive events
- Meaning: worker read source data or created an export archive.
- Join: tenant_id, export_id, and job_id; request_id is supporting context only.
- Health: freshness and required-field completeness travel with every case.

All sources retain original producer decisions, use UTC event and ingestion
times, forbid sampling for this scope, and preserve immutable event exports for
incident evidence under the service retention policy.

## Detection logic
- Claim: for the same tenant, export, and duplicate job, alert when the worker
  records `execution_authorized`, or when an object read or archive creation
  occurs, within 15 minutes after admission.
- Do not interpret `admission_decision=accepted_for_evaluation` as final
  acceptance. Preserve late and reordered final decisions in the case.
- A missing worker decision after 90 seconds is `coverage_degraded`, not proof
  of compromise; route it urgently because the response deadline is at risk.
- Severity: critical when a read or archive exists; high for final duplicate
  authorization; high coverage-degraded when a final decision is absent.
- Deliver: original and final decisions, all three clocks, source health,
  tenant and job joins, worker revision, reads, archives, replay record,
  active release, and approved maintenance context.

## Response
- Runbook: RB-EXPORT-REPLAY-002
- First validate source health and final-decision meaning; do not wait for
  attribution before pausing when final acceptance or data access is present.
- Preserve the envelope, replay record, worker trace, object-access query, and
  archive state before terminating workers when the pause has bounded new work.
- Open an incident on final duplicate authorization, any read or archive, loss
  of containment, cross-tenant evidence, or an unbounded telemetry gap.
- Close as confirmed incident, contained unsafe execution, detection defect,
  telemetry defect, authorized test, or unresolved escalation—never merely
  `false positive`.

## Test and release evidence
### FX-004 — state-semantics fixtures
- Version: rule 5, event schema 12
- Cases: API admission then worker rejection; final duplicate authorization;
  read after duplicate; missing final decision; late, duplicate, reordered,
  and mismatched-tenant events.
- Expected: the admission-only case does not claim execution; each unsafe path
  and source failure produces its distinct case and severity.

### E2E-019 — quarterly production canary
- Authorization: release owner and Security on-call; dedicated canary tenant;
  no customer source; observer may stop on any unexpected read or route delay.
- Expected: duplicate is rejected before read, no compromise page opens, the
  canary result proves the route can page from a deliberately injected unsafe
  final-decision fixture, and both pages reach their owners within 2 minutes.
- Last result: 2026-07-18, passed after evaluator version 19; evidence E2E-019.
- Limit: proves the canary path and routing at that time, not recall for every
  replay bypass or continued source health.

## Quality, tuning, and limits
- Review volume, duplicates, source delay, acknowledgement, decision time, and
  the share of cases whose promised behavior evidence supports.
- Authorized replay tests use a named canary tenant and expiring change record;
  they are enriched, not silently allow-listed.
- Blind spots: a distinct valid job, missing object instrumentation, or a read
  outside the 15-minute window. Compensating controls are tenant authorization,
  export-volume limits, and archive-publication authorization.
- Suppression requires exact tenant and test identity, approval, expiry, and a
  fixture proving final duplicate authorization still alerts.
- Retire only when duplicate execution is impossible by architecture or a
  tested replacement supports the same containment decision.

The corrected rule is not simply quieter. It now distinguishes an intermediate admission from a final decision, treats delayed evidence as a coverage problem, and escalates actual data access. Those are three different operating states and should not share one vague alert outcome.

Prove the route, not only the match

Small fixtures should exercise ordinary behavior, the promised threat, exact threshold boundaries, missing fields, duplicates, late arrival, and reordered events. Historical replay reveals volume and known benign patterns, but silence in a replay does not prove recall when the attack behavior is absent.

A safely authorized simulation tests whether production-equivalent events survive collection and normalization. An end-to-end test continues through case creation, enrichment, routing, acknowledgement, runbook use, authority, and a bounded containment decision. Record event, ingestion, alert, acknowledgement, decision, and containment times. A correct query routed to an abandoned queue is a failed detection.

Test again after changes to producers, schemas, parsers, enrichment, joins, windows, thresholds, severity, suppression, routing, or containment authority. Observe-only rollout may be appropriate while measuring uncertain volume; it is unsafe when a high-confidence signal needs immediate action. Define that choice and its promotion evidence before deployment.

Tune without erasing the claim

Classify noise before changing the rule. Benign automation, an authorized but risky action, duplicate cases, absent context, and a true false match require different repairs. Add trustworthy enrichment, deduplicate, narrow the logic, improve the event, or change the underlying control. Do not suppress activity merely because responding to it is expensive.

Every threshold, exclusion, severity change, and suppression should retain its reason, reviewer, evidence, scope, expiry where applicable, and a regression test for the original threat. Retirement needs the same discipline: name the threat coverage removed, prove any replacement, disable stale routes and dashboards, and leave an explicit residual gap when no replacement exists.

A maintained specification lets another engineer challenge the control without reverse-engineering a query. They can see what the detection claims, which evidence can support that claim, how failure announces itself, what happens when it fires, and which danger remains outside its sight.