Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Security event schema v1

rullst-security::LiveSecurityEvent is the bounded event contract rendered by Studio/Nexus and accepted by the process-local security store. Its current schema version is exported as SECURITY_EVENT_SCHEMA_VERSION = 1. The package also embeds and exports the JSON Schema 2020-12 document as LIVE_SECURITY_EVENT_V1_JSON_SCHEMA; its packaged source is security-event-v1.schema.json.

This is an application telemetry envelope, not a remote SIEM transport. The optional local spools provide bounded persistence and one explicit authenticated-journal mode, but the schema itself does not provide delivery, retention, correlation, acknowledgement, retry, dead-letter handling, source identity, or regulatory evidence.

JSON fields

Fieldv1 contract
schema_versionInteger 1. Legacy JSON without the field deserializes as v1; locally stored events are normalized to v1.
event_typeNon-empty uppercase ASCII letters, digits, and underscores; maximum 64 bytes. Invalid values become SECURITY_EVENT.
detailsUnstructured human-readable UTF-8 text; maximum 2 KiB and truncated only at a valid character boundary. It must not be parsed as authorization data.
client_ipCanonical IPv4/IPv6 string or unknown. Forwarded headers are not implicitly trusted.
timestamp_strAbsolute RFC 3339 timestamp. Invalid local timestamps are replaced at ingestion.
verified_hmactrue only when a connected verifier validated an HMAC for that exact event. It does not prove the event’s semantic claim or source identity. push_local_event always forces it to false.

Example:

{
  "schema_version": 1,
  "event_type": "RBAC_DENIAL",
  "details": "Authenticated principal denied access to the resource",
  "client_ip": "192.0.2.4",
  "timestamp_str": "2026-08-27T15:30:00.000Z",
  "verified_hmac": false
}

Producer rules

New local producers should use LiveSecurityEvent::local(...) and SecurityStore::push_local_event(...). This path:

  1. assigns schema v1 and an RFC 3339 timestamp;
  2. validates/bounds the type and detail text;
  3. canonicalizes the IP address;
  4. removes any caller-provided local HMAC claim; and
  5. stores the event in the bounded 50-entry process-local buffer.

The buffer is deliberately a dashboard snapshot. Loss on restart, eviction at capacity, and absence of a consumer are expected properties, not successful external delivery.

Compatibility rule

Within the stable v12 line:

  • fields cannot be removed, renamed, or change meaning;
  • a new required field or incompatible type requires a new schema version;
  • additive optional fields require tolerant consumers and a changelog entry;
  • event-type additions are compatible, so consumers need an unknown fallback;
  • consumers must not infer trust from verified_hmac alone; and
  • all compatibility claims apply to JSON, not field order in serialized text.

The version-one contract has source-controlled serialization, legacy-input, normalization, size, UTF-8, and CEF-injection tests. DurableSiemSpool can persist normalized unsigned v1 values in a local single-process file with exact byte/record quotas, versioned length/digest frames and restart validation. AuthenticatedSiemSpool is a distinct opt-in file format that authenticates sequence, named rotation key, predecessor and exact payload before JSON decode; verified reads set verified_hmac=true only after the complete chain passes. Release evidence still belongs to the exact RC tag SHA.

CEF boundary

format_cef_event is a serializer only. It escapes backslashes, equals signs, and CR/LF in extension values so event details cannot inject fields or records. Calling dispatch_siem_alert records a local SIEM-candidate event; it does not send or acknowledge an external alert.

Durable local spool boundary

DurableSiemSpool serializes one local event per bounded frame, calls sync_data before returning a receipt, validates every frame on reopen and rejects truncation, digest mismatch, invalid event JSON and external length changes. The SHA-256 digest detects corruption; it is not an authentication tag. The spool deliberately supplies no directory creation, multi-process lock, rotation, retention, backup, retry, dead-letter handling or remote adapter. Operators must provide a trusted, permissioned directory and one writer process per file.

Authenticated local journal boundary

AuthenticatedSiemSpool uses domain-separated HMAC-SHA256 frames and a SiemKeyRing containing one active write key plus at most seven historical verification keys. Key material is held in zeroizing storage and omitted from Debug. Reopen fails closed for an absent/wrong key, forged payload, non-canonical sequence, broken predecessor chain, removed/reordered interior frame, symlink target, quota violation or external file-length change.

The chain does not identify whether the local producer’s semantic assertion was true. Removal of a whole valid tail also needs a checkpoint retained in a separately trusted system. The journal does not rotate/compact itself or supply multi-process locking, remote delivery, retry, acknowledgement or dead-letter handling.

A future operational sink should consume the versioned JSON envelope and define redaction, backpressure, authentication, durable spool/retry/dead-letter, delivery acknowledgement, retention, and multi-tenant access separately.