Detection Rule Specification Template (Sigma, ATT&CK)
One detection as code: hypothesis, ATT&CK mapping, data fields, Sigma rule and correlation, thresholds, test cases, tuning, severity, playbook, lifecycle
Cách dùng: Use it when you add or change a SIEM detection and want it reviewed, tested and deployed like code. Fill the hypothesis and the data check first, then the Sigma rule, thresholds from your own baseline and true and false positive tests. The main pitfall is shipping a rule with no test events and no response playbook, so it silently breaks or produces alerts nobody can act on.
Xem trước
Detection Rule Specification: [Detection name]
Specification for one detection managed as code: the hypothesis it tests, its MITRE ATT&CK mapping, the data sources and log fields it needs, the rule body in Sigma format, logic and thresholds, true and false positive test cases, tuning, severity, the response playbook it starts, its owner and its lifecycle state. Based on the Sigma specification v2.1.0 (documents dated 2 August 2025, release tagged 12 September 2025; public domain), including Sigma correlation rules, and MITRE ATT&CK Enterprise v20 (October 2026). Write one specification per detection and keep it in the same repository as the rule file so that review, tests and deployment happen together. Replace every
[bracketed]value and every row marked Example. Worked examples use Corvid Commerce, a fictional SaaS company on AWS, and an original example rule that flags a burst of discovery calls made with a long-term access key from a network the company does not own.
Document control
| Field | Value |
|---|---|
| Document ID | [DET-CLD-007] |
| Detection name | [Example: Discovery burst by long-term access key from unlisted network] |
| Version | [1.2] |
| Status | [Draft / In review / Approved / Retired] |
| Lifecycle state | [Draft / Test / Stable / Deprecated] (section 12) |
| Owner | [@detection-engineer] |
| Approvers / reviewers | [@soc-lead], [@cloud-platform-lead], [@detection-engineering-lead] |
| Last updated | YYYY-MM-DD |
| Classification | Internal (detection logic is not public) |
| Rule files | [Example: detections/aws/det_cld_007_base.yml, detections/aws/det_cld_007_corr.yml] |
| Sigma specification | v2.1.0 |
| ATT&CK version mapped | Enterprise [v20] |
| SIEM target | [Example: SIEM platform name and query language] |
| Response playbook | [Example: PB-CLD-002, SOC Playbook (security/soc-playbook)] |
| Source hunt | [Example: HUNT-2026-014, Threat Hunting Plan (security/threat-hunting-plan)] |
| Next review | YYYY-MM-DD (at least every 6 months, after each ATT&CK release, after any log schema change) |
Approvals
| Role | Name | Decision | Date |
|---|---|---|---|
| Detection engineering lead | [@name] | [Approved / Changes requested] | YYYY-MM-DD |
| SOC lead | [@name] | [Decision] | YYYY-MM-DD |
| Data source owner | [@name] | [Decision] | YYYY-MM-DD |
Revision history
| Version | Date | Author | Change summary |
|---|---|---|---|
| 1.0 | YYYY-MM-DD | [@name] | Example: Created from hunt HUNT-2026-014; lifecycle Test |
| 1.1 | YYYY-MM-DD | [@name] | Example: Backup tool egress range added to known networks after FP-02 |
| 1.2 | YYYY-MM-DD | [@name] | Example: Promoted to Stable after 30 days with precision above target; ATT&CK v20 mapping checked |
Contents
- Summary
- Hypothesis and threat context
- ATT&CK mapping
- Data sources and required fields
- Logic and thresholds
- Sigma rule
- Platform query and deployment
- Test cases
- Tuning and known false positives
- Severity and alert routing
- Response
- Ownership and lifecycle
- Performance metrics
- Glossary and references
- Standard and licence note
1. Summary
| Item | Value |
|---|---|
| What it detects | Example: A single long-term IAM user access key making read-only calls to 15 or more distinct cloud APIs within 10 minutes from a source address outside Corvid Commerce networks |
| Why it matters | Enumeration of identities, infrastructure and storage is a common first step after a key is stolen; it usually happens before data access or persistence |
| Alert level | Sigma level high; SOC queue priority P2, routed as a page under the Alerting Policy (section 10) |
| First analyst action | Run triage questions T1 to T3 in playbook PB-CLD-002 |
| Expected volume (Example) | 1 to 3 alerts per month across 40 accounts after tuning |
2. Hypothesis and threat context
Hypothesis (Example): If an unauthorised party obtains a long-term access key for a Corvid Commerce IAM user, they will first establish what the key can reach by calling many different read-only APIs in a short time, from infrastructure the company does not operate.
Threat context (Example):
- Leaked keys in public repositories are found by automated scanners quickly after publication; the time between exposure and first use can be short, so detection must run in near real time.
- Attackers use the key from rented servers, anonymising networks or compromised hosts, not from the owner's usual network.
- The first calls typically confirm identity, list accounts, users, roles, storage buckets and compute instances, often across regions.
- Legitimate automation using long-term keys also calls read-only APIs, but from a stable set of networks and with a stable, small set of API names.
Out of scope for this rule: the same behaviour using temporary credentials from an assumed role (covered by [DET-CLD-008]) and console sessions (covered by [DET-IDP-011]).
3. ATT&CK mapping
| Tactic | Technique (ATT&CK Enterprise v20) | What the rule observes |
|---|---|---|
| Discovery | T1087.004 Account Discovery: Cloud Account | Calls that list users, roles or identity of the caller |
| Discovery | T1580 Cloud Infrastructure Discovery | Calls that describe instances, volumes, snapshots and networks |
| Discovery | T1619 Cloud Storage Object Discovery | Calls that list buckets and objects |
| Discovery | T1526 Cloud Service Discovery | Calls across many services in a short window |
| Initial Access, Persistence, Privilege Escalation, Stealth | T1078.004 Valid Accounts: Cloud Accounts | Context only: a valid key used from an unexpected network |
Note on tactic tags: ATT&CK v19 split the former Defense Evasion tactic
into Stealth (TA0005) and Defense Impairment (TA0112), and v20 keeps
that split. The tag appendix of the Sigma specification v2.1.0 still
lists the older tactic tags. This rule uses only the discovery tactic
tag and technique tags, which are unaffected. For rules that observe
evasion behaviour, record the v20 tactic in this table even when the
Sigma file carries the older tag.
4. Data sources and required fields
| Data source | Collection path (Example) | Latency target | Retention |
|---|---|---|---|
| AWS CloudTrail management events, all regions, organisation trail | Organisation trail to a log archive account, streamed to the SIEM | 15 minutes or less | Per Security Logging Standard (security/security-logging-standard) |
| Known network register | Configuration file detections/lists/corvid_networks.yml from the network team | Updated on change | Version control |
| Field | Example value | Used for | Required |
|---|---|---|---|
eventTime | 2026-09-14T02:11:09Z | Correlation window | Yes |
eventSource | iam.amazonaws.com | Triage context | Yes |
eventName | ListUsers | Selection and distinct count | Yes |
userIdentity.type | IAMUser | Long-term identity selection | Yes |
userIdentity.accessKeyId | AKIAEXAMPLE000000007 | Grouping | Yes |
userIdentity.arn | arn:aws:iam::111122223333:user/svc-reporting | Owner lookup | Yes |
sourceIPAddress | 192.0.2.44 | Known network filter | Yes |
userAgent | [client string] | Triage context | Recommended |
awsRegion | eu-west-1 | Triage context | Recommended |
errorCode | AccessDenied | Triage context (failures are counted) | Recommended |
recipientAccountId | 111122223333 | Scope across accounts | Yes |
Field names follow the provider's log record format. If your pipeline renames fields (for example to a common schema), add a Sigma processing pipeline that maps the names, and test it (section 8).
5. Logic and thresholds
The detection has two parts:
- Base rule (low level, not alerted on its own): one event where a
long-term IAM user key calls a read-only API (
List,DescribeorGetprefix) from a source address outside the known network register, excluding calls that the provider makes on the user's behalf. - Correlation rule (alerted): for one access key, the number of distinct API names seen by the base rule within 10 minutes is 15 or more.
Threshold derivation (Example):
| Input | Value | Source |
|---|---|---|
| Baseline window | 30 days, all 40 accounts | HUNT-2026-014 baseline |
| Keys with any base-rule event in the window | 23 | Hunt query Q2 |
| Highest distinct API count in any 10-minute window, keys with no hunt finding (21 of 23) | 9 | Hunt query Q3 |
| Highest single value observed from a legitimate tool | 12 (backup tool, later added to the known network register) | Hunt finding F-02 |
| Distinct API count in the red team test of a leaked key | 41 in the first 10 minutes | Purple team exercise PT-2026-05 |
| Chosen threshold | 15 | Above every legitimate value with margin, well below observed attacker behaviour |
Why distinct API names and not event count: automation that pages through results produces many events with the same API name. A distinct count separates "many calls to one API" (automation) from "a few calls to many APIs" (enumeration).
Known blind spots:
- An attacker who calls fewer than 15 distinct APIs, or spreads calls
over more than 10 minutes, is not detected by this rule. Hunt for slow
enumeration periodically (Threat Hunting Plan,
security/threat-hunting-plan). - Calls from a network listed in the register (for example through a compromised corporate host) are filtered out by design.
6. Sigma rule
The rule below is an original example written for this template. The
two documents live in one file separated by ---, as the Sigma
correlation specification allows. The base rule has a name so the
correlation can reference it.
title: Read-Only Cloud API Call by Long-Term Access Key From Unlisted Network
id: bdcef88a-4611-4b7d-8e6b-1cbdbd72fff1
name: det_cld_007_base
status: stable
description: >
A long-term IAM user access key made a read-only API call from a source
address that is not in the organisation's known network register.
Low value alone; used by the correlation rule det_cld_007.
references:
- https://attack.mitre.org/techniques/T1580/
author: Corvid Commerce Detection Engineering (Example)
date: 2026-09-20
modified: 2026-10-24
tags:
- attack.discovery
- attack.t1087.004
- attack.t1580
- attack.t1619
- attack.t1526
logsource:
product: aws
service: cloudtrail
detection:
selection_identity:
userIdentity.type: IAMUser
userIdentity.accessKeyId|startswith: AKIA
selection_readonly:
eventName|startswith:
- List
- Describe
- Get
filter_known_networks:
sourceIPAddress|cidr:
- 198.51.100.0/24
- 203.0.113.0/25
filter_provider_on_behalf:
sourceIPAddress|endswith: .amazonaws.com
condition: all of selection_* and not 1 of filter_*
falsepositives:
- Automation using a long-term key from a network missing from the register
- Administrators using a personal key while travelling
level: low
---
title: Discovery Burst by Long-Term Access Key From Unlisted Network
id: 698fa8bf-e676-496e-8859-8b9ff5d82d15
name: det_cld_007
status: stable
description: >
One long-term access key called 15 or more distinct read-only APIs
within 10 minutes from unlisted networks, consistent with enumeration
after credential theft.
author: Corvid Commerce Detection Engineering (Example)
date: 2026-09-20
modified: 2026-10-24
correlation:
type: value_count
rules:
- det_cld_007_base
group-by:
- userIdentity.accessKeyId
timespan: 10m
condition:
field: eventName
gte: 15
falsepositives:
- New inventory or backup tool rolled out before its egress range was registered
level: high
Notes on the example:
- The CIDR ranges are documentation ranges (RFC 5737) standing in for the real register. In production, load the register through a processing pipeline placeholder instead of editing the rule.
- Access key ID prefixes are a provider convention (long-term keys and temporary keys use different prefixes); check the provider documentation before relying on them.
generateis omitted, so only the correlation query is produced and the base rule does not alert on its own.- The base rule keeps
status,date,modified,falsepositivesandlevel: lowso it can also run on its own for hunting. Strictly, the correlation specification reserves meta information for the outermost correlation rule in a multi-document file; remove these fields from the base document if your tooling enforces that. - Both documents carry
status: stablebecause the specification is at version 1.2 (Stable). While the detection is in Test, setstatus: test(section 12).
7. Platform query and deployment
| Item | Value |
|---|---|
| Converter and version | [Example: sigma-cli with the backend for your SIEM, pinned versions in the lock file] |
| Processing pipeline | [Example: pipelines/corvid_cloudtrail.yml (field mapping, network register placeholder)] |
| Converted query location | [Example: build/det_cld_007.query, generated in CI, never edited by hand] |
| Schedule | [Example: Every 5 minutes, look-back 15 minutes to cover log latency] |
| Deployment path | Pull request, CI conversion and tests, review by a second detection engineer, automatic deployment to the SIEM |
| Rollback | Revert the pull request; the pipeline redeploys the previous version |
Deployment checklist:
- Converted query reviewed by a second engineer.
- Test cases in section 8 pass in CI against the converted query.
- Alert title includes the detection ID and links to this specification.
- Response playbook link present in the alert body.
- Suppression (section 9.3) configured.
8. Test cases
| Test ID | Type | Input | Expected result | Status |
|---|---|---|---|---|
| TP-01 (Example) | True positive | 41 events, 18 distinct read-only APIs, key AKIAEXAMPLE000000007, source 192.0.2.44, within 6 minutes | One alert for that key | Pass |
| TP-02 (Example) | True positive, boundary | Exactly 15 distinct APIs within 9 minutes | One alert (condition is greater than or equal) | Pass |
| TN-01 (Example) | True negative, boundary | 14 distinct APIs within 10 minutes | No alert | Pass |
| TN-02 (Example) | True negative, window | 20 distinct APIs spread over 25 minutes, at most 8 in any 10-minute window | No alert | Pass |
| FP-01 (Example) | Known false positive, filtered | 30 distinct APIs from 198.51.100.10 (registered network) | No alert | Pass |
| FP-02 (Example) | Known false positive, filtered | Backup tool from its registered egress range | No alert after tuning v1.1 | Pass |
| NEG-01 (Example) | Out of scope | 25 distinct APIs by an assumed role session (AssumedRole, key prefix ASIA) | No alert (covered by DET-CLD-008) | Pass |
| SCH-01 (Example) | Schema | Events with userIdentity.accessKeyId missing | Rule does not error; event ignored; data quality alert raised | Pass |
Example true positive event (one of the 41, synthetic):
{
"eventTime": "2026-09-14T02:11:09Z",
"eventSource": "s3.amazonaws.com",
"eventName": "ListBuckets",
"awsRegion": "eu-west-1",
"sourceIPAddress": "192.0.2.44",
"userAgent": "[client string]",
"userIdentity": {
"type": "IAMUser",
"arn": "arn:aws:iam::111122223333:user/svc-reporting",
"accessKeyId": "AKIAEXAMPLE000000007"
},
"recipientAccountId": "111122223333"
}
Run the tests in three places: in CI against the converted query using stored events, in a staging SIEM index after each pipeline change, and end to end once a quarter by generating real events with a dedicated test key in a sandbox account (then deactivate the key).
9. Tuning and known false positives
9.1 Known false positives
| ID | Cause | Handling | Owner |
|---|---|---|---|
| KFP-01 (Example) | Backup tool used a long-term key from a new egress range | Range added to the network register (v1.1); tool migration to workload identity tracked | [@platform-lead] |
| KFP-02 (Example) | Administrator using a personal key from home during an incident | Expected to stay as an alert; triage confirms with the person through a second channel | SOC |
| KFP-03 (Example) | Third-party security assessment with an agreed key | Time-boxed exception (section 9.2) | [@security-assessment-lead] |
9.2 Exceptions
Exceptions are time-boxed (at most [Example: 30 days]), approved by the SOC lead, recorded in the exception list with an expiry date and implemented as a filter in the processing pipeline, never as a change to the threshold.
| Exception ID | Scope | Reason | Approved by | Expires |
|---|---|---|---|---|
| EXC-DET-031 (Example) | Key of user ext-assessor | Approved cloud security assessment | [@soc-lead] | YYYY-MM-DD |
9.3 Suppression
After an alert, suppress further alerts for the same key for [Example: 60 minutes] and attach new events to the open case, so one enumeration does not create a dozen cases.
10. Severity and alert routing
| Layer | Value | Meaning |
|---|---|---|
Sigma level | high (correlation), low (base rule) | Prompt review needed when the correlation fires |
| SOC queue priority (Example) | P2: analyst picks up within 30 minutes, 24x7 | Set by the SOC routing policy; the alert is routed as a page under the Alerting Policy (ops/alerting-policy), which defines page, ticket and log routes but not P1 or P2 |
| Incident severity | Decided during triage using the Incident Severity Matrix (ops/incident-severity-matrix) | A P2 alert can become a SEV1 incident |
Escalation rule (Example): raise to P1 automatically when the same key also triggers DET-CLD-003 (audit log change) or DET-CLD-005 (key created for another user) within 60 minutes.
11. Response
- Playbook: PB-CLD-002, SOC Playbook (
security/soc-playbook), starting at triage questions T1 to T3. - Enrichment in the alert (Example): key owner from the IAM
inventory, network owner and country of the source address, distinct
API list, first and last event time, accounts touched, and whether
the key appears in any open secret scanning alert, plus any
GetSessionTokenorGetFederationTokencall signed with the key, because those sessions survive key deactivation (playbook step C3). - Do not test the key or contact the source address.
- Feedback: the analyst sets the case disposition (true positive, benign true positive, false positive) so the metrics in section 13 can be computed.
12. Ownership and lifecycle
| State | Entry criteria | Behaviour | Sigma status |
|---|---|---|---|
| Draft | Hypothesis and data check done | Runs only in development; no alerts | experimental |
| Test | All section 8 tests pass; reviewed | Runs in production, alerts to a review queue, not to on-call | test |
| Stable | 30 days in Test with precision at or above target and no unresolved tuning issue | Alerts routed per section 10 | stable |
| Deprecated | Replaced, data source retired, or no longer relevant | Disabled; specification kept with the related link to the replacement | deprecated |
| Responsibility | Owner |
|---|---|
| Rule logic, tests and this specification | [@detection-engineer] |
| Data source availability and field quality | [@cloud-platform-lead] |
| Network register accuracy | [@network-lead] |
| Triage and disposition | SOC shift |
| Periodic review | Detection engineering lead |
13. Performance metrics
| Metric | Formula | Target (Example) |
|---|---|---|
| Precision | True positive cases divided by all closed cases from this detection | 50% or more for a P2 rule |
| Alert volume | Alerts per month | 5 or fewer |
| Time to triage | Median of triage outcome time minus alert time | 30 minutes or less |
| Test pass rate | Passing test cases divided by all test cases at each deployment | 100% |
| Data health | Hours in the period where the source was delayed beyond its latency target, divided by hours in the period | 1% or less |
| Coverage contribution | ATT&CK techniques in section 3 with at least one Stable detection | Tracked in the coverage map |
Example (first 30 days in Test, 2026-09-20 to 2026-10-20, version 1.1): 3 alerts, 2 true positives (both from a scheduled re-run of purple team exercise PT-2026-05), 1 benign true positive (KFP-02). Precision is 2 divided by 3, or 67%. Before tuning, the 30-day backtest gave 12 alerts with the same 2 true positives, a precision of 2 divided by 12, or 17%.
14. Glossary and references
| Term | Meaning |
|---|---|
| Detection as code | Managing detections as version-controlled files with review, tests and automated deployment |
| Sigma | A generic, open format for describing log-based detections that tools convert to platform queries |
| Correlation rule | A Sigma document that counts or relates the results of other rules over a time window |
| Processing pipeline | Converter configuration that maps field names and expands placeholders for a target platform |
| Precision | Share of alerts that were true positives |
| Benign true positive | The rule matched the intended behaviour, but the activity was authorised |
| Reference | Use |
|---|---|
| Sigma Specification v2.1.0, documents dated 2 August 2025, release tagged 12 September 2025, github.com/SigmaHQ/sigma-specification (public domain) | Rule and correlation format (section 6) |
| SigmaHQ rule repository, github.com/SigmaHQ/sigma (Detection Rule License 1.1) | Community rules; reference only, not copied |
| MITRE ATT&CK Enterprise v20, 13 October 2026, attack.mitre.org | Technique mapping (section 3) |
| RFC 5737, IPv4 Address Blocks Reserved for Documentation | Example addresses |
SOC Playbook (security/soc-playbook) | Response to this detection |
Threat Hunting Plan (security/threat-hunting-plan) | Source hunt and baseline |
Security Logging Standard (security/security-logging-standard) | Required log sources and retention |
Alerting Policy (ops/alerting-policy) | Alert priority and routing |
Incident Severity Matrix (ops/incident-severity-matrix) | Severity decision in triage |
Threat Model (security/threat-model) | Threats that motivate detections |
Standard and licence note
Based on the Sigma specification v2.1.0 (SigmaHQ, 2025), which is released into the public domain. The example Sigma rules in this template are original and are not taken from the SigmaHQ rule repository, whose rules are licensed under the Detection Rule License (DRL) 1.1; if you add a SigmaHQ rule, keep its author, source URL and licence as DRL 1.1 requires. MITRE ATT&CK technique and tactic names and IDs are used under the ATT&CK terms of use: The MITRE Corporation (MITRE) hereby grants you a non-exclusive, royalty-free license to use ATT&CK® for research, development, and commercial purposes. Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy. "© 2026 The MITRE Corporation. This work is reproduced and distributed with the permission of The MITRE Corporation." MITRE ATT&CK and ATT&CK are registered trademarks of The MITRE Corporation. AWS, AWS CloudTrail and other product names are trademarks of their owners; this template is not affiliated with or endorsed by them. Check the current Sigma specification and ATT&CK release before use. Original text written for this collection. Template licence: MIT.
Template liên quan
Attack Tree Analysis Template
Attack tree for one attacker goal: AND/OR tree as list and Mermaid, leaf cost/skill/likelihood, path analysis, countermeasures
Kỹ thuật bảo mậtCIAM Solution Design Template (Passkeys, OIDC, FAPI 2.0)
Journeys and risk, proofing, passkeys and step-up, recovery, OAuth/FAPI profiles, consent and GDPR rights, B2B2C, fraud, scale, KPIs, migration
Kỹ thuật bảo mậtCloud Security Posture Review Template (CSA CCM v4.1)
Periodic cloud posture review: scope, shared responsibility, CSPM findings by CCM v4.1 domain, identity, exposure, data, logging, drift, risks, actions, trend