NightBeacon CMD
The SOC platform we built to run our own. Now you choose who runs it.
Detection engineering has a credibility problem: a rule that compiles and references the right-looking fields can still fail silently in production, and nothing about that failure announces itself. A query that never matches anything looks identical to a quiet, well-tuned detection, right up until an incident responder goes looking for an alert that should have fired.
I wanted to find out whether an AI agent could be held to a stricter standard than that. The agent, built against Splunk, has one task: for a given MITRE ATT&CK technique and tenant, either produce a detection it can prove works against that environment's data, or report back why it can't yet. To test it, I built a local two-customer lab: one environment representative of a typical mid-maturity Splunk deployment with realistic, imperfect telemetry, and one representative of an environment with... less usable telemetry. This piece walks through one full run of the agent against both, including the parts that weren't as pretty.
Rather than one prompt trying to hold an entire tenant's security posture in its head at once, the agent runs as three narrow modules that hand off in sequence, each scoped to only the tools its job requires.
Inventory audits what's indexed, what's field-extracted, and what detections are already deployed, characterized against live data rather than assumed from documentation. It also checks the tooling landscape: is there an alerting mechanism in place that would actually surface a new detection to an analyst?
Gap Analysis takes Inventory's findings, fetches the requested technique's current MITRE ATT&CK detection strategy, and searches live for existing open-source detection content. It diffs what MITRE and the open-source community say a detection needs against what Inventory found actually deployed and populated, and hands Authoring a verdict: covered, broken, missing, or unverifiable with the data on hand.
Authoring takes Gap Analysis's verdict and either verifies an existing detection against production history, tunes one that's structurally sound but underperforming, or writes a new one, then runs it against historical data and keeps tuning until what fires is something an analyst could actually act on.
Each module only sees what its job needs. Inventory never queries MITRE's site. Authoring doesn't do its own open-source research. That narrowness is deliberate: a model with the whole picture in front of it at every step is a model that can quietly paper over a gap in one stage with a guess borrowed from another.
Think of it less like one detective working a case alone, and more like how evidence actually moves through a real investigation. One person logs exactly what's at the scene before anyone touches it. A separate person checks that against what the case actually requires, not what would be convenient to find. Only then does a specific person act, and they act on what was actually logged and actually required, not on a hunch. That's a chain of custody, and it's what Inventory, Gap Analysis, and Authoring do for each other: nobody downstream re-does the previous handler's work, and nobody skips a handoff to save time.
One deliberate limitation: the agent does not fire synthetic attack samples at a tenant's index to confirm a detection catches them. That's reasonable in an isolated lab, but writing fabricated attack telemetry into a live, monitored SIEM to test a detection is itself a risky write action against production infrastructure. Recall (whether a detection would catch a real attack it hasn't already seen) is left an open, explicitly unmeasured question rather than something the agent claims to validate.
The first lab environment had three saved searches already on the books for credential-dumping detection (MITRE T1003.001, LSASS Memory) before this run touched anything. Inventory's job was to check what each one actually references, not what its name claims. One, aimed at LSASS dumping via rundll32.exe and comsvcs.dll's MiniDump export, filters on two fields, Image and CommandLine, that don't exist anywhere in this index. The sourcetype it queries is indexed and populated, the same sourcetype every other detection in this environment runs against; it simply never extracts those two fields.
This isn't a tuning problem, and it isn't a query that's too broad or too narrow. It's a detection that has been reporting a quiet, well-tuned appearance while never once evaluating real activity, because the data it needs isn't configured to arrive in the form it expects. No red-team exercise is required to find this: the proof is in the field list.
MITRE's current detection strategy for this technique describes exactly this pattern as its second stage: a process opens a full-access handle to lsass.exe, then writes a dump file. The recommendation here isn't to leave the rule alone. A detection that can structurally never fire is worse than having no detection at all: it sits in the search head looking active while reporting coverage that doesn't exist. Authoring's recommendation was to disable it and document exactly why, rather than quietly rewrite it into something that won't mean anything without first fixing the underlying field extraction.
That's a smaller action than it might look like from the outside. A disabled detection with a documented reason is a tracked gap, not a forgotten one: whoever owns this environment now has one specific field extraction to fix, and a specific, already-written detection to turn back on and tune for real the moment they fix it. Nothing here got quietly buried. It got handed off, with the next step already written down.
The second existing detection, built to catch processes opening a memory-readable handle on lsass.exe, already worked in the sense that it fired on genuine memory-read attempts. It also fired on routine, legitimate activity: of 162 access events in the available window, seven came back as results, and four of those were WMI enumerating processes, Windows Backup taking a shadow copy snapshot, Microsoft Defender running a scan, and a one-off handle wininit.exe picks up when it creates lsass.exe in the first place.
None of those four were excluded on a hunch. Each one was confirmed against a specific access mask and module in its call stack that only makes sense for the process claiming it. Each got its own line in a new allowlist rather than a blanket exclusion rule. The Defender entry is pinned to the exact platform version currently installed, on purpose: when that version changes, the entry stops matching, and Defender starts showing up in results again until the allowlist is updated.
The remaining three results are the more interesting outcome. None of them received a verdict, because the available evidence didn't support one either way:
lsass.exe with the memory-dump API present in its call stack. That could be a sysadmin pulling a routine crash dump, or it could be credential theft. No process-creation record exists for that process ID in the available window, so there is no command line, parent process, or user to check. Authoring's conclusion: this needs a person to confirm.lsass.exe. Here Authoring went further on its own: it pivoted into the raw process-creation record for that host and identified who launched it, an administrator account, interactively, from the desktop. That narrows the question considerably, but doesn't answer it. An administrator manually dumping a sensitive process is routine on some days and exactly what a SOC should want to know about on others.All three results remain in Splunk, unresolved, specifically because Authoring didn't have enough evidence to resolve them responsibly. The recommendation to retire the detections this one replaces, and to disable the one described above that can never fire, were both written into the report as actions for a human with write access to take, not actions Authoring took on its own.
The second lab environment presented the opposite case: a working credential and a live connection into an index with nothing in it. Not "nothing relevant to this technique," nothing at all: zero sourcetypes, zero fields, zero events, confirmed three separate ways (by sourcetype, by field, and by deployed detection) before Gap Analysis even started.
Gap Analysis still ran its full live research pass, the same MITRE ATT&CK fetch and open-source search the first environment received, because the technique's requirements don't change by customer, only the available data does. Four real open-source references came back: two SigmaHQ rules for the access pattern, a SigmaHQ rule for the dump filenames themselves, and a Splunk ESCU detection with a tuning macro already built in. Every one of them depends on fields this index simply doesn't have.
The verdict: a real coverage gap, but a data gap, not a detection gap. Writing a detection anyway was the available shortcut, and it would have been the wrong one. A query built against fields that don't exist returns zero matches today, and zero matches on an index with zero events is indistinguishable from a quiet, well-tuned detection. The honest label here is "not covered." Gap Analysis's report named exactly what's missing to change that: Sysmon process-access, file-creation, and registry telemetry, plus the Splunk add-on needed to actually extract the relevant fields, with the ESCU search identified as the recommended starting point once that data exists.
MITRE ATT&CK, T1003.001: OS Credential Dumping: LSASS Memory
MITRE ATT&CK, Detection Strategy DET0363
SigmaHQ, proc_access_win_lsass_susp_access_flag.yml
SigmaHQ, proc_access_win_lsass_memdump.yml
SigmaHQ, win_security_susp_lsass_dump_generic.yml
Splunk Security Content (ESCU), Detect Credential Dumping through LSASS access
Splunk Security Content (ESCU), Windows Possible Credential Dumping