SIEM Core
A zero-runtime-dependency SIEM log-streaming core for PHP. Produce one normalized security event and it hands you back exactly the bytes a real SIEM ingests: Splunk HEC, Elastic ECS, ArcSight CEF, Graylog GELF, or JSON.
SIEM Core is a zero-runtime-dependency log-streaming core for PHP. You produce one normalized security event and it hands you back exactly the bytes a real SIEM ingests: a Splunk HEC envelope, an Elastic ECS document, an ArcSight CEF line, a Graylog GELF message, or generic NDJSON. Nothing else. No HTTP, no queue, no credentials, no framework.
Format here, deliver elsewhere
Log streaming to a SIEM splits cleanly into two jobs, and this package is deliberately only the first. Formatting turns a normalized event into each SIEM wire schema: pure, deterministic, dependency-free, and security-critical, since CEF injection lives here. Delivery ships those records over the network with SSRF-guarded egress, batching, retries and secrets, and that is the Laravel wrapper. Keeping the formatting core free of I/O means the escaping that stops log injection is small, framework-agnostic and testable in isolation.
One Event, Every Schema
Normalized SiemEvent
One immutable, transport-neutral value object: a stable id, timestamp, action, category, outcome, severity, optional actor and target, source IP, message, and an already-flattened context bag.
Five Formatters
SplunkHecFormatter, EcsFormatter, CefFormatter, GelfFormatter and JsonFormatter, each mapped to its target SIEM real schema. Swap one for another with no other change.
Injection-Safe Escaping
The security-critical part, the escaping that stops CEF and log injection, is isolated in the formatters, small enough to review and test on its own.
StreamSink Interface
A pure interface for delivery. The core ships no implementation beyond a FakeStreamSink for tests; the real sink is the delivery wrapper concern.
Batch Is Just Map
One record per event. A batch is the formatter mapped over many events, and framing (NDJSON newlines, HEC concatenation, syslog envelopes) is the transport job, not the formatter.
Zero Runtime Dependencies
PHP 8.4 and the standard library. Nothing to audit downstream, nothing to keep patched.
Why the split matters
The formatting core is pure and side-effect-free, so the part that must not be exploitable (log injection into a SIEM) is isolated from the part that must be operationally robust (network delivery). Each is testable and replaceable on its own.