feat(go): advance validation sidecar toward production

This commit is contained in:
Luna 2026-07-22 01:52:19 -07:00
parent 6a06eba255
commit f85c2e831a
No known key found for this signature in database
92 changed files with 8881 additions and 91 deletions

View file

@ -0,0 +1,141 @@
// SPDX-License-Identifier: GPL-3.0-or-later
package events
import (
"sort"
"strings"
)
// RuleCatalog returns the stable operator-facing metadata currently exposed by
// Python ruleops.list_rules. Conditions remain data, so auditors can inspect
// what the binary will match without reading Go source or loading eBPF.
func RuleCatalog(execRules ExecRuleEngine) []map[string]any {
builtinExec := map[int]bool{100001: true, 100002: true, 100003: true, 100004: true}
records := make([]map[string]any, 0,
len(execRules.Rules)+len(DefaultSyscallRuleEngine().Rules)+len(DefaultHostRuleEngine().Rules))
for _, rule := range execRules.Rules {
origin := "configured"
if builtinExec[rule.SID] {
origin = "builtin"
}
conditions := map[string]any{}
if len(rule.PathPrefixes) > 0 {
conditions["path_prefixes"] = append([]string(nil), rule.PathPrefixes...)
}
if len(rule.ExecComms) > 0 {
conditions["exec_comm"] = sortedStringKeys(rule.ExecComms)
}
if len(rule.ParentComms) > 0 {
conditions["parent_comm"] = sortedStringKeys(rule.ParentComms)
}
if rule.ArgvRegex != "" {
conditions["argv_regex"] = rule.ArgvRegex
}
if len(rule.ParentExclude) > 0 {
conditions["parent_exclude"] = sortedStringKeys(rule.ParentExclude)
}
records = append(records, map[string]any{
"sid": rule.SID, "event": "exec", "origin": origin,
"severity": rule.Severity, "classtype": rule.Classtype,
"signature": "exec_rule." + rule.Classtype,
"msg": rule.Message, "conditions": conditions,
})
}
for _, rule := range DefaultSyscallRuleEngine().Rules {
records = append(records, map[string]any{
"sid": rule.SID, "event": "syscall", "origin": "builtin",
"severity": rule.Severity, "classtype": rule.Classtype,
"signature": "syscall_rule." + rule.Classtype,
"msg": rule.Message,
"conditions": map[string]any{
"syscalls": sortedStringKeys(rule.Syscalls),
"predicate": "built-in predicate",
},
})
}
for _, rule := range DefaultHostRuleEngine().Rules {
conditions := map[string]any{"events": sortedStringKeys(rule.Events)}
if len(rule.Comms) > 0 {
conditions["comm"] = sortedStringKeys(rule.Comms)
}
if len(rule.ParentComms) > 0 {
conditions["parent_comm"] = sortedStringKeys(rule.ParentComms)
}
if rule.PeerPublic != nil {
conditions["peer_public"] = *rule.PeerPublic
}
if len(rule.PeerPorts) > 0 {
conditions["peer_ports"] = sortedIntKeys(rule.PeerPorts)
}
if len(rule.PeerPortExclude) > 0 {
conditions["peer_port_exclude"] = sortedIntKeys(rule.PeerPortExclude)
}
if len(rule.LocalPorts) > 0 {
conditions["local_ports"] = sortedIntKeys(rule.LocalPorts)
}
if len(rule.LocalPortExclude) > 0 {
conditions["local_port_exclude"] = sortedIntKeys(rule.LocalPortExclude)
}
if len(rule.PathPrefixes) > 0 {
conditions["path_prefixes"] = append([]string(nil), rule.PathPrefixes...)
}
if len(rule.TargetUIDs) > 0 {
conditions["target_uids"] = sortedIntKeys(rule.TargetUIDs)
}
if len(rule.TargetGIDs) > 0 {
conditions["target_gids"] = sortedIntKeys(rule.TargetGIDs)
}
if len(rule.CapabilitiesAny) > 0 {
conditions["capabilities_any"] = sortedStringKeys(rule.CapabilitiesAny)
}
if len(rule.ModuleNames) > 0 {
conditions["module_names"] = sortedStringKeys(rule.ModuleNames)
}
if rule.ArgvRegex != "" {
conditions["argv_regex"] = rule.ArgvRegex
}
eventTypes := sortedStringKeys(rule.Events)
records = append(records, map[string]any{
"sid": rule.SID, "event": strings.Join(eventTypes, ","), "origin": "builtin",
"severity": rule.Severity, "classtype": rule.Classtype,
"signature": "host_rule." + rule.Classtype,
"msg": rule.Message, "conditions": conditions,
})
}
sort.SliceStable(records, func(i, j int) bool {
leftSID, rightSID := records[i]["sid"].(int), records[j]["sid"].(int)
if leftSID != rightSID {
return leftSID < rightSID
}
return records[i]["event"].(string) < records[j]["event"].(string)
})
return records
}
func FindRule(records []map[string]any, sid int) map[string]any {
for _, record := range records {
if record["sid"].(int) == sid {
return record
}
}
return nil
}
func sortedStringKeys(values map[string]bool) []string {
result := make([]string, 0, len(values))
for value := range values {
result = append(result, value)
}
sort.Strings(result)
return result
}
func sortedIntKeys(values map[int]bool) []int {
result := make([]int, 0, len(values))
for value := range values {
result = append(result, value)
}
sort.Ints(result)
return result
}