Skip to content

feat(daemon): ardur-kernelcaptured Slice 1 — always-on eBPF daemon - #82

Merged
gnanirahulnutakki merged 2 commits into
devfrom
feat/epicA-slice1-daemon
Jul 1, 2026
Merged

feat(daemon): ardur-kernelcaptured Slice 1 — always-on eBPF daemon#82
gnanirahulnutakki merged 2 commits into
devfrom
feat/epicA-slice1-daemon

Conversation

@gnanirahulnutakki

Copy link
Copy Markdown
Member

Summary

Epic A Slice 1 — the ardur-kernelcaptured foreground daemon binary that wires the existing kernelcapture library components into a runnable process.

Refs: #63 (Epic A: host-level kernel audit layer), #66 (daemon/launcher task).

What this ships

  • go/cmd/ardur-kernelcaptured/main.go — daemon struct, routing index (cgroup_id → session_id), JSONL evidence-log writer, flags, signal handling
  • go/cmd/ardur-kernelcaptured/daemon_linux.go — eBPF consumer: LoadAndAttachProcessExecEBPF → tracepoints → ringbuf → processKernelEvent
  • go/cmd/ardur-kernelcaptured/daemon_unsupported.go — non-Linux stub (logs warning, returns error; control plane still runs)
  • go/cmd/ardur-kernelcaptured/daemon_test.go — unit tests for routing, session lifecycle, evidence-log append, sanitize, prune
  • go/pkg/kernelcapture/linux_ebpf_daemon_linux.go — exports ProcessExecEBPFHandles, LoadAndAttachProcessExecEBPF, NewRingbufProcessSourceFromRingbufReader

Runtime flow

start
 └── ListenDaemonUnixSocketServer (SO_PEERCRED auth, fail-closed)
      ├── register_session → cgroup_id → session_id index + ProcessTreeScope + Correlator
      ├── end_session      → remove from index
      └── session_status   → registry lookup

eBPF ringbuf (Linux only)
 └── sched_process_exec/exit → routeEvent (cgroup fast-path, PID-tree slow-path)
      └── Correlator.Correlate → SyntheticKernelReceipt
           └── JSONL append → <evidence-dir>/<session-id>/kernel_receipts.jsonl

prune goroutine (default 30s)
 └── remove routing entries for sessions expired in registry

The socket path (/run/ardur/kernelcapture/control.sock) and protocol (kernelcapture.daemon.v1) match python/vibap/kernel_correlation.py — the ardur run bridge (PR #81) is the counterpart producer.

Explicitly NOT in Slice 1

  • Privileged system-service install / systemd unit (Slice 2)
  • cgroup creation and assignment (left to ardur run bridge)
  • Enforcement / kill-switch actions (Slice 4)
  • bpffs map pinning, socket ownership hardening, crash-recovery

Tests

go test ./cmd/ardur-kernelcaptured/... ./pkg/kernelcapture/...

All 16 Go packages green on macOS (non-Linux path). Linux eBPF path verified in the previous session against Colima kernel 6.8 (--privileged --pid=host).

Wire existing kernelcapture libraries into a runnable
always-on daemon (foreground/dev mode only):
- Unix-socket control plane with SO_PEERCRED auth
- DaemonSessionRegistry honoring register_session TTL
- cgroup→session routing index + ProcessTreeScope per session
- Correlator per session; routes eBPF events → SyntheticKernelReceipt
- Per-session JSONL evidence log (kernel_receipts.jsonl)
- Linux: LoadAndAttachProcessExecEBPF (sched_process_exec+exit)
- Non-Linux: stub that logs a warning and returns immediately
- Session expiry pruner goroutine

New exported surface in kernelcapture:
- ProcessExecEBPFHandles / LoadAndAttachProcessExecEBPF
- NewRingbufProcessSourceFromRingbufReader

Out of scope (stubs): privileged install (Slice 2), enforcement (Slice 4).

Refs: Epic A (#63), task #66
if err != nil {
return err
}
defer f.Close()
CaptureLoss was accumulated monotonically across the event loop, causing
every kernel receipt after the first malformed record to carry an inflated
drop count. Reset the struct immediately after each delivered event so the
loss field reflects only drops observed since the previous good event.

Add TestRouteEvent_SlowPathPIDTreeMatch to cover the PID-tree scan branch
(CgroupID=0 scope, event CgroupID misses cgroupIndex) which had no test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants