Skip to main content

Minimal SIEM Contracts

The minimal SIEM ingestion/search contract is accepted in ADR-0013. OP-012 implements the first runtime slice: tenant log source registration, normalized ingest, ClickHouse-backed search/detail, deterministic SIEM rules, and generic alert projection.

Event Flow

log.source.registered
-> log.event.received
-> log.event.normalized
-> security.alert.created
-> alert.created projection

log.event.received means a raw log was accepted inside the tenant boundary. log.event.normalized means the event was parsed, enriched, redacted, and made searchable. Phase 1 search queries normalized events only.

security.alert.created is the SIEM-specific detection event. It carries rule metadata, matched conditions, log event refs, normalized event refs, source log IDs, confidence, and severity. Existing alert.created stays the generic platform alert event for the current UI, ticketing, evidence, and delivery workflow. When projected, generic alert.created uses the same correlation_id and points its causation_id back to the SIEM detection event.

Tenant And Source Identity

Shared collectors must identify tenant scope cryptographically:

  • mTLS certificate identity,
  • ADR-0009 agent/collector identity,
  • tenant-scoped service-account identity.

Source IP, hostname, syslog facility, provider display name, or log payload contents are not tenant identity.

Runtime APIs

  • POST /api/v1/log-sources
  • GET /api/v1/log-sources
  • GET /api/v1/log-sources/{source_id}
  • PATCH /api/v1/log-sources/{source_id}
  • POST /api/v1/logs/ingest
  • GET /api/v1/logs/search
  • GET /api/v1/logs/{event_id}

The Phase 1 search API is intentionally small:

  • tenant scope,
  • time range,
  • severity,
  • asset_id,
  • log_source_id,
  • event type/category,
  • bounded free-text over redacted summaries,
  • pagination and hard limits.

There is no custom SIEM query language in this contract.

Storage

  • Postgres/RLS stores log_sources.
  • ClickHouse stores normalized_log_events.
  • The API service accepts bounded batches of up to 100 events.
  • The worker consumes log.event.received in NATS mode and writes normalized events to ClickHouse before rule evaluation.

No new application pods are required; the existing API and worker services own the runtime path.

Retention

  • hot: searchable, 30-day default.
  • warm: slower search, 90-day default.
  • cold: archive, 6-year default for HIPAA/GLBA-aligned audit/compliance needs.

Durations are tenant-configurable within platform-defined bounds.

References

  • docs/adr/ADR-0013-minimal-siem-ingestion-search.md
  • docs/architecture/minimal-siem-ingestion-search-contracts.md
  • specs/events/log.source.registered.v1.schema.json
  • specs/events/log.event.received.v1.schema.json
  • specs/events/log.event.normalized.v1.schema.json
  • specs/events/security.alert.created.v1.schema.json
  • specs/openapi.yaml
  • specs/asyncapi.yaml