GitHub
11/13/2026, 5:48 PMsanta_events but never reach the log sinks or the alert rules. A blocked execution cannot page anyone or reach a SIEM.
Change
After an event upload is stored, osctrl-tls forwards the events to the log sinks and to the alert rules.
• Log sinks: each upload is sent as one JSON array under a new category santa, with the same fields as GET /api/v1/santa/{env}/events.
• The file and stdout sinks write it. The pass-through sinks (HTTP, Kafka, Kinesis, S3, Logstash, Splunk, Elastic, Graylog) need no change.
• The DB sink skips it, because the events are already in santa_events.
• Alert rules: new source santa_event. Rules match on decision, file_sha256, file_path, file_name, executing_user, team_id, signing_id, cd_hash and bundle_id, with the existing substring or regex patterns, on one field or on any.
• Example: field decision with pattern BLOCK alerts on every blocked execution.
• Cooldown and dedupe are reused. The dedupe entity is the node plus the file hash, so a rule alerts once per node and binary within its cooldown.
• UI: the alert rule form offers "Santa events" when Santa is enabled. An existing rule stays editable when it is not.
• CLI: the --source help of the alert rule command lists santa_event.
• Docs: pkg/santa/README.md has a new "Events in log sinks and alert rules" section.
pkg/santa gains StoreEvents, which returns the stored events; EventUpload now wraps it.
Security and operational impact
• Untrusted fields: event fields are written by the Santa client. The notification detail is one line (DECISION path sha256=... user=...) with control characters removed and at most 1024 bytes, so a crafted file path cannot forge lines in an email. The file hash in the dedupe entity is cut to 64 bytes.
• Permission: santa_event rules are gated like log-content rules (superuser or full query tier), because the events carry endpoint paths and user names. This is stricter than the environment admin level needed to read Santa events.
• Forgery guard: the osquery log endpoint now rejects log_type: "santa" with 400, so an osquery node cannot forge Santa events into the sinks.
• Sink failure: a failing sink is logged and the upload still returns 200. The events are already stored, and a retry from Santa would store them twice. Events are therefore not re-sent to a sink that was down.
• Upgrade behavior: a sink with no category filter starts receiving santa batches once Santa is enabled. A filtered sink needs santa added to its categories.
• Requirements: alert matching runs in osctrl-tls and needs --alerts-enabled. No new flag or setting.
• No schema change and no change to the sync protocol. alert_rules.source is an existing string column.
Not included
• The same forgery guard for carve.meta and carve.data. An osquery node can post those log types today; that is existing behavior and left for a separate change.
• Translations for the new source label and help text. The alert form's source labels are English only today.
• Reading Santa events back through the logs API. The Santa events API already serves them.
Validation
• go test ./pkg/santa/... ./pkg/alerts/... ./pkg/logging/... ./pkg/logsinks/... ./pkg/apiclient/... ./cmd/api/... ./cmd/tls/... ./cmd/cli/...
• go vet and gofmt -l on the touched packages
• make openapi-check
• npm --prefix frontend run check and npm --prefix frontend test (793 tests)
• golangci-lint run on the touched packages reports 13 errcheck issues in pkg/logging and cmd/tls/handlers/carves.go. None are in lines changed here.
New tests cover:
• Matcher: field-scoped and regex rules, node and environment scope, the detail and entity format, control characters and oversized values in event fields, and a stored rule loading into the snapshot and reaching the dispatcher.
• TLS handler: an upload reaching the sink as a santa JSON array and the matcher with the authenticated node, a failing sink not failing the upload, an empty upload sending nothing, an upload with no logger configured, and the osquery log endpoint rejecting log_type: "santa".
• API: an alert admin without the query tier cannot create a santa_event rule.
• File sink: a santa batch is written with its type.
• Frontend: the source is hidden when Santa is off, and a Santa rule is created with its field and pattern.
Not verified: delivery through a real webhook or email channel, real Splunk, Elastic or Graylog sinks, and the UI in a browser.
jmpsec/osctrlGitHub
11/13/2026, 6:15 PM