cboxdk / laravel-siem
The SIEM log-streaming delivery engine for Laravel — a durable transactional outbox, queued batched delivery with retry/backoff/dead-letter/circuit-breaker, SSRF-guarded HTTP egress, encrypted destination secrets, and PII redaction, on top of the framework-agnostic cboxdk/siem core.
Requires
- php: ^8.4
- cboxdk/laravel-ssrf: ^1.0
- cboxdk/siem: ^0.1
- illuminate/bus: ^12.0 || ^13.0
- illuminate/contracts: ^12.0 || ^13.0
- illuminate/database: ^12.0 || ^13.0
- illuminate/http: ^12.0 || ^13.0
- illuminate/queue: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^3.5 || ^4.0
- pestphp/pest-plugin-laravel: ^3.0 || ^4.0
README
The SIEM log-streaming delivery engine for Laravel: a durable transactional outbox, queued batched delivery with retry, dead-letter, and a per-stream circuit breaker, SSRF-guarded HTTP egress, encrypted destination secrets, and per-field PII redaction — shipping normalized security events to Splunk HEC, Elastic (ECS), Graylog (GELF), ArcSight/syslog (CEF), or any HTTP JSON collector.
This package is the Laravel wrapper over the framework-agnostic
cboxdk/siem core. The core owns the event model
and the formatters (the shape of the data); this package owns delivery (the
network, the durability, the secrets). An audit binding in
cboxdk/laravel-id consumes this layer to
stream a tamper-evident audit trail — that binding is a separate package.
Installation
composer require cboxdk/laravel-siem php artisan vendor:publish --tag="siem-migrations" php artisan vendor:publish --tag="siem-config" # optional php artisan migrate
The service provider is auto-discovered. Destination secrets use Laravel's
encrypter, so an APP_KEY is required (every Laravel app has one).
At a glance
use Cbox\LaravelSiem\Contracts\{LogStreams, StreamDispatcher}; use Cbox\LaravelSiem\Enums\Destination; use Cbox\Siem\ValueObjects\SiemEvent; // 1. Register a destination (endpoint SSRF-checked; secret encrypted, revealed once). app(LogStreams::class)->create( name: 'splunk-prod', destination: Destination::SplunkHec, endpointUrl: 'https://http-inputs.example.splunkcloud.com', secret: 'your-hec-token', redaction: ['password' => 'drop', 'email' => 'hash'], ); // 2. In your own DB transaction, write the event to the outbox (a cheap insert). DB::transaction(function () use ($event) { // ... your business write ... app(StreamDispatcher::class)->dispatch($event, app(LogStreams::class)->enabled()); }); // 3. The queued pump batches, redacts, formats, and ships it — off the request thread.
What it guarantees
- Deny-by-default — no enabled stream, nothing delivered.
- At-least-once, unordered — the outbox row commits in your transaction; a rolled-back caller leaves no orphan. Duplicates are possible; dedup by event id.
- Never blocks the request — all delivery is queued.
- Bounded everything — triple-bounded batches (records/bytes/age), bounded exponential backoff with jitter, a hard retry cap into a dead-letter, a bounded outbox with an explicit backpressure policy, and a per-stream circuit breaker.
- Safe egress — SSRF-guarded and DNS-pinned, TLS verification always on, secrets encrypted at rest and scrubbed from logs, PII redacted before formatting.
Destinations
| Destination | SIEM | Framing |
|---|---|---|
splunk_hec |
Splunk HEC | NDJSON to the collector event endpoint, Authorization: Splunk <token> |
elastic_ecs |
Elastic / Kibana | ECS JSON documents (NDJSON) |
graylog_gelf |
Graylog | GELF 1.1 over HTTP (never UDP) |
cef_http |
ArcSight / syslog | CEF lines over HTTP |
generic_json |
any HTTP collector | neutral single-line JSON |
Testing
Compose Cbox\LaravelSiem\Testing\InteractsWithLogStreams into your TestCase to
run the whole pipeline in memory: fakeStreamSink() binds an in-memory
FakeStreamSink, createLogStream(...) registers through the real registry, and
pumpStream($id) runs a delivery cycle synchronously. FakeHttpTransport programs
the HTTP fake for testing the real HttpStreamSink.
Requirements
- PHP 8.4+
- Laravel 12.x or 13.x
- A queue connection, a database, and an
APP_KEY.
Documentation
Full documentation lives in docs/.
The event core
The normalized SiemEvent, the formatters, and their escaping/threat model are
provided by cboxdk/siem. This package claims
only the Laravel delivery layer.
Credits
License
The MIT License (MIT). See LICENSE.md.