Zum Inhalt springen

Observability: hashverkettetes SIEM-Protokoll und Render-Berichterstattung

Das Observability-Modul ist die Implementierung für den Laufzeitzustand: ein manipulationssicheres, hashverkettetes SIEM-Ereignisprotokoll, die Aggregation der Render- und Pilot-Berichterstattung, ein HSM-Audit-Protokoll sowie ein vollständiger Satz von No-op-Metrik- und Trace-Implementierungen, sodass die Instrumentierung jederzeit aufrufbar bleibt.

Eine kanonische Seite pro Belang. Die Observability-VerträgeContextAwareExceptionInterface, SpectrumInterface, JobNotificationInterface und das DegradationPolicy-Enum — sind dokumentiert unter Contracts / Observability. Diese Seite dokumentiert die konkrete Laufzeitzustands-Implementierung. Die beiden sind komplementär, keine Duplikate: Lesen Sie die Seite zu den Verträgen für die SPI und diese Seite für die SIEM-Protokollierungs-, Berichterstattungs- und Audit-Bereiche.

Terminal-Fenster
composer require nextpdf/core:^3

Dieses Modul überführt den Laufzeitzustand der Engine in eine dauerhafte, überprüfbare Ausgabe.

HashChainSiemEventLog ist die sicherheitskritische Komponente. Sie implementiert den SiemEventEmitter-Vertrag und schreibt ein JSON-Lines-Protokoll, in dem der Hash jedes Datensatzes SHA-256(prev_hash_bytes || canonical_event_bytes) ist. Diese lineare Hashkette macht das Protokoll manipulationssicher: Das Ändern eines beliebigen Bytes, das Löschen einer Zeile oder das Umordnen von Zeilen bricht die Kette. verifyIntegrity() durchläuft die Datei und gibt den Index des ersten inkonsistenten Datensatzes zurück oder null, wenn die Kette intakt ist. readAll() streamt die Datensätze. Ein prozessbezogenes, beratendes flock(LOCK_EX) schützt den kritischen Abschnitt vom Tail-Lesen bis zum anschließenden Anhängen, sodass gleichzeitige PHP-Prozesse auf derselben Datei keine Datensätze verschachteln. Das Design benennt seine Grenze klar: Es ist eine lineare Hashkette, kein Merkle-Baum nach RFC 6962 — ausreichend für Manipulationssicherheit, nicht für effiziente Inklusionsbeweise. Der Quellcode weist ebenfalls darauf hin. SiemEvent trägt das typisierte Ereignis mit toCanonicalJson(). SiemEventSeverity und SiemEventType klassifizieren es. CorrelationContext und CorrelationIdGenerator reichen eine Korrelations-ID durch zusammengehörige Ereignisse weiter.

RenderReportBuilder, RenderReport, PilotReportAggregator und PilotSummary bilden die Berichterstattungsfläche (@since 5.1.0). Der Aggregator sammelt RenderReports und erzeugt eine PilotSummary, die sich als Array, JSON oder Markdown rendern lässt — in dem Format, das eine Betriebsprüfung verwenden kann.

HsmAuditLogInterface / HsmAuditEvent zeichnen HSM-gestützte Signaturoperationen für die Sicherheitsschicht auf. MetricsCounterInterface, MetricsGaugeInterface, MetricsHistogramInterface und TraceSpanInterface definieren die Metrics-/Trace-Formen. Die NoOp*-Implementierungen stellen einen vollständigen, inerten Fallback bereit, sodass die Engine Metriken und Spans ohne konfiguriertes Backend emittieren kann.

Stabilität: experimentell. Das SIEM-Protokoll ist intern nach Zyklen getaggt und trägt kein eingefrorenes Semver-@since; die Berichterstattungsfläche ist @since 5.1.0. Die Flächen sind funktionsfähig und getestet, aber die API-Formen können sich weiterentwickeln. Behandeln Sie das Protokoll-Format (kanonisches JSON + Hashkette) als den stabilen Vertrag und die PHP-API als noch nicht abschließend gefestigt.

KlasseWichtige MitgliederRolle
HashChainSiemEventLogemit(SiemEvent), verifyIntegrity(): ?int, readAll(): GeneratorManipulationssicheres, hashverkettetes SIEM-Protokoll
SiemEventtoCanonicalJson()Typisiertes SIEM-Ereignis
SiemEventSeverity / SiemEventType (Enums)KlassifizierungEreignisschweregrad und Ereignistyp
CorrelationContext / CorrelationIdGeneratorKorrelationsweitergabeKorreliert zusammengehörige Ereignisse
RenderReportBuilder / RenderReportBerichtszusammenstellungBericht pro Render-Vorgang (@since 5.1.0)
PilotReportAggregatoraddReport(), count(), getSummary(), toJson(), toMarkdown(), exportReportsJson()Aggregiert Render-Berichte (@since 5.1.0)
PilotSummarytoArray(), toJson(), toMarkdown()Betriebsprüfungszusammenfassung (@since 5.1.0)
HsmAuditLogInterface / HsmAuditEventHSM-Audit-DatensatzAudit-Protokoll für HSM-Operationen
NoOpSiemEventEmitter, NoOpMetricsCounter, NoOpTraceSpan, …inerte FallbacksVollständige No-op-Implementierungen

Führen Sie composer docs:generate-api-php -- --module=Observability für die vollständige PHPDoc-Tabelle aus.

Emittieren Sie ein Ereignis und überprüfen Sie die Integrität des Protokolls.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Observability\Siem\HashChainSiemEventLog;
use NextPDF\Observability\Siem\SiemEvent;
$log = new HashChainSiemEventLog('/var/log/nextpdf/siem.jsonl');
$log->emit(new SiemEvent(/* type, severity, payload */));
$firstBroken = $log->verifyIntegrity();
echo $firstBroken === null
? "SIEM chain intact.\n"
: "Tamper detected at record {$firstBroken}.\n";

Kapseln Sie den Emitter so, dass ein Protokollierungsfehler im Signatur-Hotpath eine lokale Entscheidung bleibt und keine nicht abgefangene Ausnahme auslöst.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Observability\Siem\HashChainSiemEventLog;
use NextPDF\Observability\Siem\Exception\SiemEmitterException;
use NextPDF\Observability\Siem\SiemEvent;
use Psr\Log\LoggerInterface;
final readonly class AuditedSiemSink
{
public function __construct(
private HashChainSiemEventLog $log,
private LoggerInterface $fallback,
) {}
public function record(SiemEvent $event): void
{
try {
$this->log->emit($event);
} catch (SiemEmitterException $e) {
// Do not let SIEM I/O abort the signing path; record and continue.
$this->fallback->critical('SIEM emit failed; event not chained.', [
'error' => $e->getMessage(),
]);
}
}
}
  • emit() wirft bei einem Schreibfehler SiemEmitterException. Ein Aufrufer im Signatur-Hotpath muss dies kapseln und lokal entscheiden, ob er die Ausnahme unterdrückt, einen erneuten Versuch unternimmt oder abbricht. Der Emitter entscheidet nicht für Sie.
  • verifyIntegrity() gibt den Index des ersten fehlerhaften Datensatzes zurück oder null. Ein Ergebnis ungleich null bedeutet, dass das Protokoll ab diesem Punkt kompromittiert ist — vertrauen Sie Datensätzen ab dieser Stelle nicht.
  • Das beratende flock ist prozessbezogen und auf dieselbe Datei beschränkt. Hostübergreifende Nebenläufigkeit erfordert eine Out-of-Band-Senke (etwa eine Weiterleitung an syslog). Gehen Sie nicht davon aus, dass die Dateisperre maschinenübergreifend koordiniert.
  • Dies ist eine lineare Hashkette, kein Merkle-Baum. Sie beweist Manipulationssicherheit, aber keine effizienten Inklusionsbeweise. Vermarkten Sie sie nicht als Letzteres.
  • Die NoOp*-Fallbacks sind vollständig und inert. Verzweigen Sie nicht je nach Backend-Verfügbarkeit, um „Arbeit zu sparen“ — das No-op kostet bereits nichts.

emit() liest den Hash des vorherigen Datensatzes und hängt unter einer Dateisperre eine Zeile an — O(1) pro Ereignis zuzüglich des Sperraufwands. verifyIntegrity() ist O(n) in der Anzahl der Datensätze, weil es die gesamte Kette durchläuft. Führen Sie es planmäßig aus, nicht im Hotpath. Die Berichtsaggregation ist linear in der Anzahl der Berichte. Das Reproduzierbarkeitsprofil ist structural: Ereignisse und Berichte tragen Zeitstempel und Korrelations-IDs, sodass sich zwei Durchläufe in diesen Feldern unterscheiden, während die Kettenstruktur deterministisch ist.

Das SIEM-Protokoll ist eine Sicherheitskontrolle. Seine Manipulationssicherheit hängt davon ab, dass die Protokolldatei und der Verifizierungsschritt geschützt sind: Speichern Sie die Datei auf zugriffskontrolliertem Speicher, der Append-Vorgänge zuverlässig unterstützt, führen Sie verifyIntegrity() planmäßig aus und leiten Sie Datensätze Out-of-Band weiter, sodass eine Host-Kompromittierung die Historie nicht unbemerkt umschreiben kann. Ereignisse können sensiblen Kontext enthalten. Wenden Sie die Log-Scrubbing-Pflicht des Projekts an, bevor das Ereignis konstruiert wird, nicht nachdem es verkettet wurde, weil ein bereinigtes Umschreiben die Kette brechen würde. Das HSM-Audit-Protokoll zeichnet Signaturoperationen auf und ist selbst sicherheitsrelevant. Behandeln Sie es mit denselben Schutzmaßnahmen. Siehe das Bedrohungsmodell der Engine unter /modules/core/security/.

Dieses Modul erhebt keinen normativen Anspruch in Bezug auf die PDF-Spezifikation. Es implementiert Mechanismen zur Protokollintegrität und Observability, deren Design sich an den Praktiken zur Protokollverwaltung und Integritätsprüfung in NIST SP 800-92 orientiert — eine im Quellcode dokumentierte Ausrichtung an einem Kontrollrahmenwerk, keine PDF-Zitierung auf Chunk-Ebene. Die Konformität der Dokumente, die die Engine produziert, wird durch die Oracle- und Golden-Suites validiert, die unter /modules/core/conformance/ beschrieben sind.