Overview
cboxdk/siem
cboxdk/siem is a zero-runtime-dependency SIEM log-streaming core for PHP
8.4+. You build one normalized security event; it produces exactly the bytes a
real SIEM ingests — Splunk HEC, Elastic ECS, ArcSight/syslog CEF, Graylog GELF,
or generic NDJSON. It does no network I/O, holds no credentials, and depends on
no framework.
The two-tier story
Streaming logs to a SIEM is two jobs, and this package is only the first:
- Format — turn a normalized event into each SIEM's wire schema. Pure, deterministic, dependency-free, and security-critical (record injection is prevented here). This package.
- Deliver — ship the records: SSRF-guarded egress, TLS, batching, a queue,
retries, a dead-letter queue, encrypted secrets. The Laravel wrapper
cboxdk/laravel-siem(a separate package, built later), plus alaravel-idaudit binding.
Splitting them keeps the security-sensitive formatting core small and testable in isolation, and lets the delivery concerns live where a framework can do them properly.
Mental model
your app ──▶ SiemEvent ──▶ StreamFormatter ──▶ formatted record ──▶ StreamSink
(normalize) (per-SIEM schema) (a string) (deliver: wrapper)
SiemEvent— one immutable, transport-neutral value object.StreamFormatter—format(SiemEvent): string, one record per event; five implementations ship. A batch is the formatter mapped over many events; framing is the transport's concern.StreamSink— a pure delivery interface. The core ships no implementation (only aFakeStreamSinkfor tests); the real sink is the wrapper's.
Sections
- Quickstart — build an event and format it, in one read.
- Requirements — PHP and extension versions.
- Core concepts — the event model and each formatter's mapping to its SIEM's real schema.
- Extension points — write your own formatter against the contract.
- Security — the record-injection threat model, the CEF escaping guarantee, and the honest scope boundary.
Scope
This is a formatting core. Network delivery — SSRF-safe egress, TLS, auth, secret
storage, batching, retries — is deliberately out of this package and lives in
cboxdk/laravel-siem. See Security for the boundary.