Cyber: Sigma detection over governed telemetry
The problem
Sigma is the industry-standard way to write portable detection logic, but running a Sigma rule usually means shipping it to a SIEM that's a separate system from the one holding your audit trail, your identity graph, and your access controls. When a rule fires, the analyst pivots to a different tool to trace the alert back to a host, a user, and — eventually — a provenance chain a compliance reviewer can trust. Two systems, two access models, two places for the trail to break.
The scenario
A SOC analyst wants to catch a specific lateral-movement pattern — a process running as SYSTEM immediately after a user-level logon from an unfamiliar host — across ingested EDR and SIEM telemetry, then confirm the same account touched other hosts in the same window, all without exporting anything to a separate detection engine.
Import the rule, query the telemetry it protects
Sigma rules import directly into Relata's governance layer — detection logic and the governed store it runs against are the same system.
from relata import RelataClient, GovernanceClient
with RelataClient(
"http://localhost:9090",
bearer_token="relata-dev",
purpose="threat_hunting",
) as client:
gov = GovernanceClient.from_client(client)
# Import a Sigma rule — same governed store, no SIEM round-trip
gov.import_sigma(open("sigma/lateral-movement-system-escalation.yml").read())PURPOSE 'threat_hunting'
-- Full-text hunt across ingested telemetry for the pattern the Sigma rule targets
SELECT hostname, process_name, command_line, event_time
FROM AttackEvent
WHERE MATCH(command_line, 'runas', PHRASE)
ORDER BY event_time DESC
LIMIT 50
WITH PROVENANCE;Typed SDK snippet
from relata import RelataClient, GovernanceClient
with RelataClient(
"http://localhost:9090",
bearer_token="relata-dev",
purpose="threat_hunting",
) as client:
gov = GovernanceClient.from_client(client)
gov.import_sigma(open("sigma/lateral-movement-system-escalation.yml").read())
# Hunt for the pattern across governed telemetry, provenance attached
hits = client.query(
"SELECT hostname, process_name, command_line, event_time "
"FROM AttackEvent WHERE MATCH(command_line, 'runas', PHRASE) "
"ORDER BY event_time DESC LIMIT 50 WITH PROVENANCE"
)
for row in hits:
print(row["hostname"], row["process_name"], row["event_time"])
# Reconstruct the account's footprint across other hosts in the window
account_hosts = client.query(
"SELECT * FROM RESOLVE_IDENTITY('svc_account', MODE => 'cluster')"
)Why the trail doesn't break
- Detection logic and the data plane are one system.
GovernanceClient.import_sigma()loads a standard Sigma rule directly into the same store the query runs against — no export to a SIEM and back. See Governance. - Full-text search is native, not bolted on.
MATCH(...)withPHRASE,FUZZY, orSTEMMEDmodes runs against a custom BM25 index over the same governed rows — see Hybrid Search for the full retrieval-signal breakdown. - Every hit carries provenance.
WITH PROVENANCEmeans an incident-response write-up can cite exactly which ingested record, from which sensor, produced each match. - Identity resolution reaches across hosts and accounts the same way it reaches across a financial or OSINT investigation.
RESOLVE_IDENTITYis the same operator used everywhere else in the platform — a SOC analyst is one query away from the identity graph, not a separate UEBA product.
See also
- Governance —
import_sigma,PURPOSE, and the audit hash chain - Hybrid Search —
MATCHmodes and the BM25 engine internals - OSINT: cross-platform identity fusion — the same
RESOLVE_IDENTITYoperator used for account/actor correlation - Query Cookbook — the full graph-operator surface for lateral-movement and pivot queries