The module lifecycle stageExperimental
The module has requirements for installation

Do I need this module?

Use it if you want to:

  • Collect security-relevant events (audit, runtime, application) in a single canonical format.
  • Route events to Loki, Elasticsearch, Splunk, or other SIEM/storage based on source and severity.
  • Let other teams define event extraction (Shipper) while you own the registry (SecurityEventDefinition) and destinations.

If you only need generic log collection without security-event validation or routing, the log-shipper module alone may be enough.

How do I enable delivery to Loki?

  1. Create a ClusterSecurityEventDestination with spec.type: Loki and your Loki endpoint/auth/tls. More details about the configuration and examples can be found in CR and Examples.
  2. Create a ClusterSecurityEventConfig that references this destination in spec.destinations and defines which sources are allowed via spec.enabledSources or spec.enabledSourcesMasks.
  3. Ensure you have at least one SecurityEventDefinition so the controller creates the ClusterLogDestination for the gateway; and at least one Shipper that produces events matching your config.

Events are not reaching the destination. What should I check?

  • Source allowlist — in ClusterSecurityEventConfig you must list the source in enabledSources or enabledSourcesMasks. Source format —
    • clusterSecurityEventShipper/<name of ClusterSecurityEventShipper>/<source> (e.g. clusterSecurityEventShipper/kube-audit/kube-apiserver)
    • podSecurityEventShipper/<namespace>/<name of PodSecurityEventShipper>/<source> (e.g. podSecurityEventShipper/my-ns/audit/my-component)
  • Masks — if using enabledSourcesMasks, * matches any substring including /. You cannot set both enabledSources and enabledSourcesMasks.
  • Severity — defaultSeverityThreshold filters by .event.severity; events below the threshold for that config are not sent to the corresponding destinations.
  • Registry — if SecurityEventDefinition is used, events whose (event.code, source.component) pair is not in the registry are dropped at the gateway. Ensure the Shipper’s produces[].eventCode and source match a SecurityEventDefinition.

More details about checking gateway config and logs can be found in Advanced usage.

What is the difference between PodSecurityEventShipper and ClusterSecurityEventShipper?

  • PodSecurityEventShipper is namespaced. It reads logs from pods in that namespace (KubernetesPods source). Use it for application or namespace-scoped audit/runtime events.
  • ClusterSecurityEventShipper is cluster-scoped. It can read from pods in selected namespaces (KubernetesPods) or from files on nodes (File). Use it for cluster-wide audit logs, node-level logs, or shared parsers.

Both produce events that are identified by eventCode and source; routing in ClusterSecurityEventConfig uses the same source format for both (with the appropriate prefix podSecurityEventShipper/... or clusterSecurityEventShipper/...).

How do I add a new event type?

  1. Create or reuse a SecurityEventDefinition with the desired code, severity, category, source, and fields (required optional).
  2. Create or update a PodSecurityEventShipper or ClusterSecurityEventShipper that has a spec item with produces[].eventCode matching that definition and source matching the definition’s source. Configure input, parser or parserRef, and optionally produces[].transform / enrich.
  3. Ensure a ClusterSecurityEventConfig allows this source (in enabledSources or enabledSourcesMasks) and references the destination where you want events stored.

severity and category are defined only in SecurityEventDefinition, not in Shipper.

How do I send events to an external system (OpenSearch, Elasticsearch, Splunk, etc.)?

The security-events-manager module supports sending events to several types of external storage and analytics systems: Loki, Elasticsearch, Kafka, Splunk (HEC), Vector, File, and Console. Let’s look at the setup using OpenSearch as an example.

OpenSearch is backward-compatible with the Elasticsearch API, so the Elasticsearch destination type and the _bulk/_search endpoints are used for sending events.

To configure event delivery:

  1. configure an event destination — the ClusterSecurityEventDestination resource;
  2. configure delivery rules — the ClusterSecurityEventConfig resource;
  3. ensure the cluster has at least one ClusterSecurityEventShipper or PodSecurityEventShipper producing events from the allowed sources.

Configure the destination

The destination is configured through the ClusterSecurityEventDestination resource.

For OpenSearch, the endpoint field specifies the HTTPS address of the API (via Ingress — https://opensearch-api.example.com, or internal — https://opensearch-cluster-master:9200). Authentication strategies are None, Bearer, or Basic. Server certificate verification is configured in the tls block. The index field specifies the index name or index template, for example security-events-%Y.%m.%d for daily index rotation.

Example:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventDestination
metadata:
  name: opensearch-external
spec:
  type: Elasticsearch
  elasticsearch:
    endpoint: https://opensearch-api.example.com
    # Daily index rotation. Remove the suffix for a single index.
    index: security-events-%Y.%m.%d
    auth:
      # None | Bearer | Basic.
      strategy: Basic
      username: admin
      password: P@ssw0rd-CHANGE-ME
    tls:
      # For a public Let's Encrypt certificate via Ingress.
      # If the gateway has no system CA, verification can be disabled.
      # For production — set ca (Base64 PEM) and enable verification.
      verifyCertificate: false
      verifyHostname: false
      # ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...

The auth.password and auth.token fields are stored in the resource in plain text. For production, it is recommended to create a dedicated user in OpenSearch with write-only permissions to the target index.

Configure delivery rules

Delivery rules are configured through the ClusterSecurityEventConfig resource.

The destinations field specifies the destination name set in metadata.name of the ClusterSecurityEventDestination resource. The enabledSources (or enabledSourcesMasks) field lists the sources whose events are sent to the destination. The defaultSeverityThreshold field sets the minimum severity level — events below the specified level are discarded.

Example:

apiVersion: security.deckhouse.io/v1alpha1
kind: ClusterSecurityEventConfig
metadata:
  name: opensearch-routing
spec:
  # Low | Medium | High — discards events below the threshold.
  defaultSeverityThreshold: Low
  enabledSourcesMasks:
    - clusterSecurityEventShipper/* # All cluster-scoped sources.
    - podSecurityEventShipper/* # All namespace-scoped sources.
  destinations:
    - opensearch-external # Name of the ClusterSecurityEventDestination resource.

Multiple ClusterSecurityEventDestination resources can be created and listed in the destinations of a single ClusterSecurityEventConfig — selected events will be sent to all destinations simultaneously. To split the stream by severity, use multiple ClusterSecurityEventConfig resources with different defaultSeverityThreshold values and non-overlapping destinations or enabledSources.