PHPackages                             cboxdk/siem - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. cboxdk/siem

ActiveLibrary

cboxdk/siem
===========

Zero-dependency SIEM log-streaming core for PHP: a normalized security-event value object and the formatters (Splunk HEC, Elastic ECS, ArcSight/syslog CEF, generic JSON) that turn it into what real SIEMs ingest. Framework-agnostic; the delivery/egress layer lives in the Laravel wrapper.

v0.1.0(1mo ago)21.5k↑70.2%2MITPHPPHP ^8.4CI passing

Since Jul 15Pushed 1mo agoCompare

[ Source](https://github.com/cboxdk/siem)[ Packagist](https://packagist.org/packages/cboxdk/siem)[ Docs](https://github.com/cboxdk/siem)[ RSS](/packages/cboxdk-siem/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (2)Used By (2)

cboxdk/siem
===========

[](#cboxdksiem)

A zero-runtime-dependency SIEM log-streaming **core** for PHP 8.4+. You produce one normalized security event; it hands you back exactly the bytes a real SIEM ingests — a Splunk HEC envelope, an Elastic ECS document, an ArcSight/syslog CEF line, a Graylog GELF message, or generic NDJSON. Nothing else: no HTTP, no queue, no credentials, no framework.

```
composer require cboxdk/siem
```

The two-tier picture
--------------------

[](#the-two-tier-picture)

Log streaming to a SIEM splits cleanly into two jobs, and this package is deliberately only the first one:

1. **Format** — turn a normalized event into each SIEM's wire schema. Pure, deterministic, dependency-free, security-critical (CEF injection lives here). **That is this package.**
2. **Deliver** — ship those records over the network: SSRF-guarded egress, TLS, batching, a queue, retries, a dead-letter queue, encrypted secrets. That is the Laravel wrapper **`cboxdk/laravel-siem`** (separate package), plus a `laravel-id` audit binding. **Not here.**

Keeping the formatting core free of I/O means the security-sensitive part — the escaping that stops log injection — is small, framework-agnostic, and testable in isolation, and the delivery concerns live where a framework can do them properly.

Mental model
------------

[](#mental-model)

```
your app ──▶ SiemEvent ──▶ StreamFormatter ──▶ formatted record ──▶ StreamSink
           (normalize)      (per-SIEM schema)     (a string)         (deliver: wrapper)

```

- **`SiemEvent`** — one immutable, transport-neutral value object: a stable id, when it happened, an action, a category, an outcome, a severity, an optional actor and target, an optional source IP and message, and an already-flattened `context` bag.
- **`StreamFormatter`** — `format(SiemEvent): string`, one record per event. Ships five implementations. A batch is just the formatter mapped over many events; framing (NDJSON newlines, HEC concatenation, syslog envelopes) is the transport's job.
- **`StreamSink`** — a pure interface for delivery. The core ships **no**implementation (only `Cbox\Siem\Testing\FakeStreamSink` for tests); the real sink is the wrapper's.

Quickstart
----------

[](#quickstart)

```
use Cbox\Siem\Enums\EventCategory;
use Cbox\Siem\Enums\Outcome;
use Cbox\Siem\Enums\Severity;
use Cbox\Siem\Formatters\CefFormatter;
use Cbox\Siem\ValueObjects\Party;
use Cbox\Siem\ValueObjects\SiemEvent;

$event = new SiemEvent(
    id: 'evt_01HZX',
    occurredAt: new DateTimeImmutable(),
    action: 'user-login',
    category: EventCategory::Authentication,
    outcome: Outcome::Success,
    severity: Severity::Medium,
    actor: new Party('user', '42'),
    sourceIp: '203.0.113.7',
    message: 'User 42 signed in',
    context: ['method' => 'password', 'mfa' => true],
);

echo (new CefFormatter)->format($event);
// CEF:0|Cbox|SIEM|0.1.0|user-login|User 42 signed in|5|rt=... cat=authentication act=user-login ...
```

Swap the formatter for any other with no other change:

```
use Cbox\Siem\Formatters\EcsFormatter;
use Cbox\Siem\Formatters\SplunkHecFormatter;
use Cbox\Siem\Formatters\GelfFormatter;
use Cbox\Siem\Formatters\JsonFormatter;

(new EcsFormatter)->format($event);        // Elastic Common Schema JSON
(new SplunkHecFormatter)->format($event);  // Splunk HEC envelope
(new GelfFormatter('edge-1'))->format($event); // Graylog GELF 1.1
(new JsonFormatter)->format($event);       // generic single-line NDJSON
```

The formatters, mapped to each SIEM's real schema
-------------------------------------------------

[](#the-formatters-mapped-to-each-siems-real-schema)

FormatterTargetKey schema facts`SplunkHecFormatter`Splunk HTTP Event Collector`{"time": , "sourcetype": ..., "event": {...}}`; `time` is **seconds**, not milliseconds; records concatenate as NDJSON.`EcsFormatter`Elastic Common Schema`@timestamp` (RFC-3339 UTC), pinned `ecs.version`, `event.{id,action,category[],type[],kind,outcome}`, `log.level`, `user.id`, `source.ip`, `labels.*`, custom `cbox.*`.`CefFormatter`ArcSight / syslog`CEF:0`GelfFormatter`Graylog (GELF 1.1)`version` `1.1`, `host`, `short_message`, epoch-seconds `timestamp`, **numeric** `level` 0–7, `_`-prefixed additional fields (`_id` forbidden).`JsonFormatter`generic / NDJSONdeterministic single-line, UTF-8 safe JSON.Security posture (honest scope)
-------------------------------

[](#security-posture-honest-scope)

This package **formats**; it does not deliver. So its security surface is exactly one thing, and it takes it seriously: **preventing log/record injection during formatting.** The CEF formatter is the sharp edge — a CEF record is a single syslog line, so an unescaped `|`, `=`, or newline in attacker-influenced data could forge a header field, an extension key, or a whole second event. All escaping is isolated in a tested `Cbox\Siem\Support\CefEscaper` and proven with an adversarial round-trip test. Newline neutralization is **unconditional** — there is no config flag that can turn it off.

Everything downstream of a formatted string — SSRF-safe egress, TLS, auth, secret storage, retries — is out of scope here **by design** and belongs to `cboxdk/laravel-siem`. See [`SECURITY.md`](SECURITY.md) and [`docs/security/_index.md`](docs/security/_index.md).

Requirements
------------

[](#requirements)

- **PHP 8.4+**
- **`ext-json`** — ships with core PHP.

No runtime package dependencies. No framework. See [`docs/requirements.md`](docs/requirements.md).

Documentation
-------------

[](#documentation)

Full docs live in [`docs/`](docs/index.md): a [quickstart](docs/quickstart.md), [core concepts](docs/core-concepts/_index.md) (the event model and the formatters), [extension points](docs/extension-points/_index.md) (writing your own formatter), and the [security](docs/security/_index.md) posture and escaping guarantee.

Security reporting
------------------

[](#security-reporting)

Report vulnerabilities through **GitHub Private Vulnerability Reporting** — see [`SECURITY.md`](SECURITY.md).

License
-------

[](#license)

MIT — see [`LICENSE`](LICENSE).

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance90

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b9761a79e61f2d5b9d650510dfb3555da18daf38f027aa84012c937e397e39a7?d=identicon)[cboxdk](/maintainers/cboxdk)

---

Top Contributors

[![sylvesterdamgaard](https://avatars.githubusercontent.com/u/2431914?v=4)](https://github.com/sylvesterdamgaard "sylvesterdamgaard (1 commits)")

---

Tags

arcsightauditcefecselasticlog-streamingndjsonobservabilityphpsecurity-eventssiemsplunk-hecstructured-loggingsyslogphpNDJSONelasticAuditsyslogECSSIEMstructured-loggingobservabilitycefsplunk-heclog-streamingsecurity-eventsarcsight

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cboxdk-siem/health.svg)

```
[![Health](https://phpackages.com/badges/cboxdk-siem/health.svg)](https://phpackages.com/packages/cboxdk-siem)
```

###  Alternatives

[babenkoivan/elastic-migrations

Elasticsearch migrations for Laravel

1962.9M10](/packages/babenkoivan-elastic-migrations)[inspector-apm/inspector-php

Inspector monitoring for PHP applications.

363.5M35](/packages/inspector-apm-inspector-php)[utopia-php/audit

A simple audit library to manage application users logs

25344.2k4](/packages/utopia-php-audit)[treblle/treblle-php

Runtime Intelligence Platform

20107.9k2](/packages/treblle-treblle-php)[hamidrezaniazi/pecs

PHP ECS (Elastic Common Schema): Simplify logging with the power of elastic common schema.

3237.4k1](/packages/hamidrezaniazi-pecs)[hafael/azure-mailer-driver

Supercharge your Laravel or Symfony app with Microsoft Azure Communication Services (ACS)! Effortlessly add email, chat, voice, video, and telephony-over-IP for next-level communication. 🚀

15146.2k](/packages/hafael-azure-mailer-driver)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
