Skip to main content
Version: Next — legacy draft snapshot

Security event export

Retained Next source

This page preserves the merged Next documentation snapshot at e1ddcf6940adb7b619ce509063749e740eecc795. It can describe implementation beyond the source revision selected for the rebuilt Next guides. Retain the implementation-scope notes below and confirm your deployed version before applying these details. This is not a current-release availability or deployment claim. For the task-based entry point, see the rebuilt guide.

Next implementation scope

The transaction fields and explicit security-event tagging described below refer to platform PR 554 (internal implementation reference), reviewed at commit 300e8a9956ada4ac628fd5fceda13855510a73b0. This scope note concerns explicit security tagging, not the separate direct-write audit-export fix in platform PR 551 (internal implementation reference). Confirm each implementation independently. These changes are not a statement that the current released platform or a customer deployment contains them. Confirm the deployed implementation before relying on these fields; source checks do not establish live ingestion or delivery.

Delphi marks the security-relevant events it emits so the observability stack can single them out and fan them out to an external SIEM. This page covers that marking — the contract, which component sets it for which event, and how to verify it. Routing those events onward to a destination is a separate concern; SigNoz operations inventories the collector container that does it.

The tag contract​

Web audit events use recordKind: Audit in SigNoz, including security/access events and managed-resource changes. Check the Web coverage table against the deployed version: the VGWK-126 / SCRUM-801 fix adds export for previously DB-only Web paths such as password reset and platform-role changes. The export path fans those events out through the SigNoz / collector configuration on the observability host.

Two log attributes carry the marking:

AttributeValue
security_eventtrue — a genuine boolean, on the log record's attributes
security_categoryone of authentication, authorization, audit, certificate

Two details are load-bearing:

  • security_event must be the boolean true. The export filter keeps a record only for the boolean after classification; a string "true" or the number 1 does not satisfy that filter by itself. Fallback classification may still mark a record from other fields or body text, so do not rely on stringly-typed values.
  • security_category is a closed set of four values. It is the export vocabulary, and it is not the same thing as the category attribute on an audit record — that one (AUTH, ROLE_MANAGEMENT, FLOW, NUMBER, SECURITY, SYSTEM) drives the Access logs UI and the audit row. Do not use one where the other belongs.

The four values live in one place in code — SECURITY_CATEGORIES in packages/logger/src/security-classification.ts — and are pinned by a test against the literals in the export collector config, so the two cannot drift apart.

Why the tag is needed​

The export collector can classify a record from its text when no service tagged it, but that fallback does not work for the platform's own audit events. An audit record's OTLP body is the bare action name (LOGIN_FAILED, ACCESS_DENIED, ACCOUNT_LOCKED), and the fallback matches phrases like "login failed" — which LOGIN_FAILED is not. Without the tag, essentially every security audit event the platform produced was dropped by the export filter.

Who sets the tag​

Event sourceHow it is tagged
TelWeb, TelPhi, and the auth/API audit emitters@delphi/logger stamps it in StructuredLogger.log(), so logSecurityEvent, logAuth, logLogout and logEntityChange all carry it
TelAPICall sites spread securityTagAttributes(...) onto a bare-pino log record — the error handler does this once for every thrown authentication/authorization error
TelPro (Kamailio)transform/kamailio_promote in the host collector tags the four trunk-admission rejects below

The tag rides both log routes. On the direct OTLP path it is a record attribute; on the stdout path it travels inside the Pino envelope, which the host collector promotes for recordKind: Audit. One event, one export.

Because the structured-logger seam sits on the whole audit surface, tagging is not limited to failures: successful LOGIN, LOGOUT and SESSION_END sign-ins are access events and are exported too. The audit category and the action decide what is a security event — CREATE / UPDATE / DELETE on ordinary business objects are audited but deliberately not exported, so routine changes do not dilute the security signal.

Which action maps to which category​

packages/logger/src/security-classification.ts is the source of truth; this is its effect.

Actionsecurity_category
LOGIN, LOGIN_FAILED, LOGOUT, SESSION_END, PASSWORD_CHANGE, PASSWORD_RESET_*, ACCOUNT_LOCKED, ACCOUNT_UNLOCKEDauthentication
REJECTED_CONNECTION, ACCESS_DENIED, PRIVILEGE_ESCALATION_ATTEMPT, PLATFORM_ROLE_CHANGE_*, PLATFORM_ROLE_SESSION_CLEANUP_FAILED, SUPER_ADMIN_RECOVERY_*authorization
SYSTEM_MANIPULATION_ATTEMPT, SECURITY_LOGS_ACCESSED, SECURITY_POLICY_MODIFIEDaudit
CREATE, UPDATE, DELETE(not exported)

An action that is not in that list is still exported, without a category, so a new action surfaces instead of disappearing. The audit log remains the authoritative record of what the platform logged.

TelPro: the trunk-admission rejects​

TelPro's Kamailio emits four rejects as structured records, and the host collector tags them:

eventsecurity_categoryReject
trunk_identify_failedcertificate, or authorization when the message does not mention TLS or a peer nameUnknown trunk, or a TLS / peer-identity verification failure
trunk_call_rejectedauthenticationThe trunk requires an X-Call-ID and it was invalid or missing (403 Forbidden)
xcall_invalidauthenticationA Janus call's X-Call-ID had no entry, so it did not resolve
xcall_missingauthenticationA Janus call arrived without an X-Call-ID at all

trunk_identify_failed is one event name for two different situations — an access-control reject and a transport-identity reject — so the category is decided from the message text.

Rejects that are not exported​

Five further rejects in kamailio.cfg are written with xlog only. They are dropped before any collector statement runs, so they cannot be tagged and do not reach the SIEM:

LocationReject
kamailio.cfg:617Transfer from an unverified source (403)
kamailio.cfg:646Transfer from an unverified source (403)
kamailio.cfg:810Authentication misconfiguration (500)
kamailio.cfg:816Source IP not authorized (403)
kamailio.cfg:835Digest username mismatch (401)

There is no BYE self-relay reject at all: the route that would classify one is defined and never called. Making these exportable means emitting them as structured records — a change to the voice application and its image, tracked separately.

Sink mode: absence of events proves nothing

Without destination credentials the export collector renders a nop pipeline and drops everything it receives — classification never runs. A healthy collector container does not mean events are leaving the deployment. Check the init script output for Export ENABLED before reading anything into a lack of security events.

Verify the tag on a running deployment​

  1. Provoke a known event. A failed sign-in or a request with a bad API key is the quickest.
  2. In SigNoz, find the record and confirm it carries security_event = true — as a boolean, not a string — and the security_category you expect.
  3. Note that the record body is still the bare action name (LOGIN_FAILED). That is expected, and is exactly why the tag exists.
  4. Confirm the event is delivered once: one record, with log_transport = 'otlp_direct' and audit.delivery_role = 'canonical'.
  5. For TelPro, place a call from an unknown source and force a TLS peer-name mismatch. Expect event = 'trunk_identify_failed' with security_category of authorization and certificate respectively.

Verify forwarding separately​

  1. Confirm SigNoz monitoring is healthy and receiving audit / access events.
  2. Enable the security-event export collector / fan-out configuration shipped with the SigNoz service.
  3. Provide destination credentials (API tokens, endpoints) for the external system.
  4. Follow the step-by-step audit verification with fresh failed-login, password-reset and role-change events. Verify each appears in SigNoz and in the external sink.

Export is best effort. A DB record alone does not prove external delivery, and enabling export does not backfill historical audit rows.

SurfaceUse
Access logsSuper Admin UI for authentication and role-management events
Audit loggingWhat the platform records as an audit event
SigNoz monitoringInvestigate raw logs, traces, and dashboards
PII redactionControls what PII leaves the collector

See also​