Skip to content

SIEM and syslog

PKIFactor can forward its audit trail in real time to a SIEM collector, over syslog. Every event written to the audit trail is also sent to the collector: certificate requests, approvals, issuances, revocations, sign-ins and sign-in failures, administrative changes, deployments, backups, license and key management events, and so on.

SIEM forwarding is included with every license.

What is sent

Aspect Value
Envelope Syslog RFC 5424, in both formats
Formats CEF (Common Event Format), or Syslog + JSON
Transports UDP, TCP, TCP + TLS
Framing over TCP and TLS Octet counting (RFC 6587): each message is preceded by its length and a space
Facility local0 to local7, auth or authpriv (default local0)
Character set UTF-8

Syslog + JSON

The message body is a JSON object:

<133>1 2026-10-26T09:14:02.512031Z 3f2a9c1e7b4d PKIFactor - LOGIN_FAILED - {"event": "LOGIN_FAILED", "action": "login", "resource_type": "session", "resource_id": "", "outcome": "failure", "reason": "invalid_credentials", "details": {...}, "username": "bob@example.com", "source_ip": "192.0.2.10"}
Field Content
event Event name, for example CERTIFICATE_ISSUED, CERTIFICATE_REVOKED, LOGIN_FAILED, SETTINGS_UPDATED
action, resource_type, resource_id What was done, on which kind of object, and its identifier
outcome success (default), failure or denied
reason When the event gives one
details All the event's data, with secrets masked
username The actor (e-mail when known, system for background tasks)
source_ip When the event carries it

Syslog severity: notice (5), or warning (4) when the outcome is failure or denied.

CEF

The CEF line is the message of the RFC 5424 envelope:

<133>1 2026-10-26T09:14:02.512031Z 3f2a9c1e7b4d PKIFactor - LOGIN_FAILED - CEF:0|ZetaCert|PKIFactor|2.0.0|LOGIN_FAILED|login:session|7|suser=bob@example.com src=192.0.2.10 cs2=session cs2Label=ResourceType outcome=failure reason=invalid_credentials cs3={...} cs3Label=Details rt=Oct 26 2026 09:14:02
CEF element Content
Vendor, product ZetaCert, PKIFactor
Version Always 2.0.0 in this version (it is not the product version)
Signature ID The event name
Name action:resource_type
Severity 3 for success, 7 for failure, 8 for denied
suser The actor
src Source IP address, when known
cs1 / cs1Label=ResourceID Identifier of the object
cs2 / cs2Label=ResourceType Kind of object
outcome, reason As in JSON
cs3 / cs3Label=Details All the event's data as JSON, secrets masked
rt Time of sending, UTC

The syslog severity of the envelope is always notice in CEF; the CEF severity carries the outcome.

Common to both formats

  • APP-NAME is PKIFactor and MSGID is the event name.
  • HOSTNAME is the host name of the backend container (in Docker, the container's short identifier unless a host name is set).
  • Secrets are masked before sending: fields whose name contains password, secret, token, api_key, private_key, passphrase, credential and similar are replaced by ***REDACTED***, and so is any value that contains a private key.
  • Not forwarded: the ACME server's own events (it is a separate service), network scan activity, and application logs that are not audit events.

Configure forwarding

  1. In the Administration workspace, open System > Settings, tab SIEM Integration (administrators only).
  2. Fill in the fields and click Save.
  3. Click Send test event (the button appears once forwarding is enabled and a host is saved).
Field Content
Enable SIEM forwarding Turns forwarding on or off
Collector host Host name or IPv4 address of the collector
Port 1 to 65535, default 514
Protocol UDP (standard syslog, port 514), TCP (reliable, port 601) or TCP + TLS (encrypted, port 6514); the ports shown are the usual ones, set the one your collector uses in Port
Log format CEF (Splunk, QRadar, ArcSight, Sentinel) or Syslog + JSON (ELK, Graylog, Datadog)
Syslog Facility local0 to local7, auth, authpriv
Verify collector TLS certificate TCP + TLS only. On by default; the collector's certificate must then be valid for the host name entered
CA Certificate (optional) TCP + TLS only. Path of a PEM file of the CA that signed the collector's certificate, as seen from inside the backend container (for example /certs/siem-ca.pem). Without it, the system CA store is used

The CA file must exist in the backend container: the default deployment mounts no directory for it, so provide the file through a volume of your own.

Saving reloads the forwarder at once: no restart is needed.

Client certificate (mutual TLS)

Some collectors require the sender to authenticate with a certificate. PKIFactor supports it, but the settings are not in the form: set them through the settings API, as paths of PEM files inside the backend container, then save the SIEM tab again (or send a test event) to reload the forwarder.

Setting Content
siem_tls_client_cert Path of the client certificate (PEM)
siem_tls_client_key Path of the client private key (PEM)

Both must be set; with either missing, no client certificate is presented.

Status

TCP + TLS forwarding with a client certificate was proved against a real syslog collector (port 6514) in August 2026 (version 1.4.7): a LOGIN_FAILED event was received, and clients without a certificate were rejected. No recorded test covers UDP, plain TCP, or each SIEM product named in the format list.

Follow the forwarding

The SIEM tab shows, when forwarding is enabled:

  • Connected to SIEM collector or Not connected;
  • Events sent and Failures since the backend started;
  • Last error, when there is one.

The Monitoring page (Oversight workspace, Fleet monitoring > Monitoring) has a SIEM / Syslog section fed by a connection check. That check sends a real test event, so the collector receives a SIEM_TEST event at each health check (every 30 minutes by default, with the revocation monitor, REVOCATION_MONITOR_INTERVAL) and after each save of the SIEM tab.

Events that could not be sent

When an event cannot be delivered (collector down, network failure), PKIFactor does not drop it:

  1. The event is written to siem_deadletter.log in the backend's log directory (the audit_logs volume in the Docker deployment).
  2. Every 2 minutes PKIFactor tries again, up to 1,000 events per round, and removes from the file those that were sent.

Events kept this way also remain in the audit trail itself, which does not depend on the SIEM.

UDP gives no delivery receipt: an event sent over UDP counts as sent even if the collector never received it. Use TCP + TLS when losing events matters.

Troubleshooting

Symptom Cause and fix
The SIEM Integration tab is missing The account is not an administrator: the Administration workspace and System > Settings are reserved to administrators
No Send test event button Forwarding is not enabled or no host is saved: tick Enable SIEM forwarding, enter the host, Save
SIEM not configured or disabled Same cause
Connection failed: ... The collector is unreachable on that port and protocol (firewall, wrong port, collector not listening on TCP)
Connection failed: ... CERTIFICATE_VERIFY_FAILED ... The collector's certificate is not trusted: set CA Certificate (optional) to the right PEM file, or check that the host name matches the certificate
Connection failed: ... No such file or directory The CA, client certificate or key path does not exist in the backend container
The test succeeds but nothing arrives (UDP) UDP has no receipt: check the firewall and the collector's UDP listener, or switch to TCP
Events arrive as one long line or are split wrongly (TCP) The collector does not expect octet-counting framing (RFC 6587); configure its input for it
The collector does not parse the fields Wrong format: match Log format with the collector's parser (CEF or JSON)
Failures keeps growing Read Last error; undelivered events wait in siem_deadletter.log and are retried every 2 minutes
SIEM_TEST events every 30 minutes Expected: they come from the health check on the Monitoring page
Via the API

# Sign in (administrator)
curl -s -c jar -X POST https://clm.example.com/api/auth/login \
  --data-urlencode "email=admin@example.com" --data-urlencode "password=$PASSWORD"

# Current configuration and forwarder status
curl -s -b jar https://clm.example.com/api/v1/admin/siem/config
curl -s -b jar https://clm.example.com/api/v1/admin/siem/status

# Configure TCP + TLS in JSON format (reloads the forwarder)
curl -s -b jar -X PUT https://clm.example.com/api/v1/admin/siem/config \
  -H "Content-Type: application/json" \
  -d '{"enabled": true, "host": "siem.example.com", "port": 6514,
       "protocol": "tcp_tls", "format": "syslog_json", "facility": "local0",
       "tls_verify": true, "tls_ca_cert": "/certs/siem-ca.pem"}'

# Optional client certificate (mutual TLS), then reload by sending a test event
curl -s -b jar -X PUT https://clm.example.com/api/v1/admin/settings \
  -H "Content-Type: application/json" \
  -d '{"settings": {"siem_tls_client_cert": "/certs/pkifactor-siem.pem",
                    "siem_tls_client_key": "/certs/pkifactor-siem.key"}}'
curl -s -b jar -X POST https://clm.example.com/api/v1/admin/siem/test-connection
protocol takes udp, tcp or tcp_tls; format takes cef or syslog_json. A failed test answers HTTP 502 with the reason. All routes are in /api/v1/docs, tag SIEM.