enodia-sentinal/CLAUDE.md
Luna d835386381
feat(go): port FIM/pkgdb/rootcheck integrity engines and add go-sidecar dashboard consumer
Adds sidecar-only, --state-dir-gated FIM, package-DB-anchor, and rootcheck
engines to the Go migration sidecar, wired into agent.Sweep/Initialize
behind the existing baseline lifecycle. Adds a read-only, schema-checked
Python dashboard consumer (go_sidecar_state_dir, /api/go-sidecar/*, Sidecar
tab) that never starts, stops, or mutates the Go sidecar's state.

Also fixes drift found while reconciling this work: enodia_sentinel/web.py
had reinvented local schema constants instead of using the canonical
enodia_sentinel/schemas.py catalog (now registers enodia.go.sidecar.v1
there and reuses ALERT_SNAPSHOT_V1/INCIDENT_V1); docs/RULES.md had drifted
from what `rules docs` actually generates for SIDs 100069-100078 (ruleops.py
was missing metadata for four SIDs and had stale drill text for four more),
now back in sync with a regression test pinning them together.

Updates CLAUDE.md, README.md, go-agent/README.md, and docs/{ROADMAP,
GO_PORT_HANDOFF,SURICATA_ASSIMILATION,THREAT_MODEL,OPERATIONS,SCHEMAS,
COMMAND_REFERENCE}.md to reflect the landed work.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQivSKBqQJsayz1xcYqWzZ
2026-07-24 09:59:09 -07:00

12 KiB

CLAUDE.md

Guidance for Claude or Claude Code agents working on Enodia Sentinel.

Project Shape

Enodia Sentinel is a zero-runtime-dependency Linux IDS/IPS/EDR platform. The core agent is pure Python standard library and should stay that way unless a dependency has clear security/operator value that cannot reasonably be achieved with stdlib. Its IPS scope is explicit prevention workflow: posture hardening, containment planning, and future reviewed --apply actions, not silent inline network blocking or automatic host mutation.

Primary functions:

  • Detect: poll detectors, optional eBPF exec/syscall rules, and typed host-event rule fixtures.
  • Prevent: posture findings plus reviewed containment/recovery plans.
  • Verify: FIM, package DB anchor, signed-package verification, rootcheck.
  • Investigate: text/JSON snapshots, incidents, HTTPS management console.
  • Respond: dry-run plans first; any state-changing action must be explicit, logged, and tested.
  • Assure: heartbeat, watchdog, self-integrity, future external anchors.

Current State Snapshot

As of 2026-07-24, the project is a local-first Linux IDS/IPS/EDR agent at package version 0.7.0. The branch has a working stdlib-only daemon, CLI, HTTPS management console, incident model, response planner, rootcheck, posture checks, file/package integrity checks, push notification backends, and optional bcc/eBPF telemetry.

An experimental, non-installing Go sidecar now lives under go-agent/. It is stdlib-only, emits enodia.event.v1 JSONL, and ports all current Python poll detectors, the exec/syscall/typed-host rule engines, opt-in cilium/ebpf exec and syscall sources, hot-path plus asynchronous enrichment, and Python-schema- compatible incidents/snapshots/hash-chain. A --state-dir-gated set of sidecar-only integrity engines (FIM, package-DB anchor, rootcheck) now also runs asynchronously off the sweep loop. Python's dashboard has an opt-in, explicitly read-only /api/go-sidecar/* consumer (go_sidecar_state_dir, the Sidecar tab) that displays this evidence without starting, stopping, or otherwise controlling the Go process. Python remains the production agent and parity oracle; do not describe the Go path as a replacement yet.

Implemented detection coverage:

  • Poll detectors: reverse_shell, ld_preload, deleted_exe, input_snooper, credential_access, stealth_network, memory_obfuscation, new_listener, new_suid, persistence, and egress.
  • eBPF exec rules: fileless execution from writable paths, reverse-shell argv, web/database service spawning shells, and curl|wget|sh style staging.
  • eBPF syscall rules: RWX mprotect/mmap, memfd_create, sensitive ptrace, seccomp changes, cross-process memory access, and memory locking.
  • Typed host-event rules: tcp_connect JSON fixtures can already exercise interpreter egress to unusual public ports; live event sources are still future work.
  • Anti-rootkit checks: hidden PIDs, /proc vs ps mismatches, hidden modules, hidden TCP/UDP/raw/special-protocol sockets, raw ICMP/SCTP-style channels, promiscuous interfaces, known LKM rootkit names, module taint, and kernel taint.

Implemented investigation/response state:

  • Alert snapshots are written as text and JSON under log_dir.
  • Incident tracking groups snapshots by process lineage and time window and exposes incident list/show/export.
  • The dashboard is HTTPS-only, token-protected off loopback, and read-only. It shows status, incidents, timelines, alerts, posture findings, integrity/watchdog state, event-rule metadata, event tail, dry-run response plans, and a local Settings menu with persistent themes. An opt-in Sidecar tab additionally displays the isolated Go migration-sidecar's retained heartbeat, alerts, incidents, and event log when go_sidecar_state_dir is configured; this consumer is schema-checked and read-only, and never starts, stops, or controls the Go process. Web tests cover the theme registry, integrity console wiring, sidecar consumer isolation, and core text/status contrast checks.
  • respond plan <incident-id> builds read-only containment/recovery plans, persists CLI-generated plans under response-plans/, and appends response-audit.log. Dashboard/API plan previews do not write artifacts.
  • rules list/show/test exposes built-in and configured event rules and lets operators test exec, syscall, and typed host-event JSON fixtures against the rule engines.
  • rules docs emits generated Markdown rule docs; docs/RULES.md is the checked-in built-in rule reference with match fields, false positives, and drill guidance.
  • baseline accept/revoke/list reconciles legitimate FIM/package/listener/SUID drift: an operator accepts an identified item with a mandatory reason, stored fingerprint-bound and audited in reconciliation.json. Acks suppress the alert only while live state matches; content kinds (fim/pkgfile) re-alert on further change, identity kinds (listener/suid) retire on TTL or revoke. The filter runs at the daemon chokepoint, fim-check, and the dashboard integrity API.
  • An optional desktop tray applet (enodia-sentinel-tray, [tray] extra with pystray/Pillow) opens the dashboard, controls the daemon via systemctl, and runs check --json quick checks. Its logic modules (tray/state.py, actions.py, notify.py) are GUI-free and tested; only tray/app.py imports GUI libs, and the core agent stays stdlib-only.
  • Optional windowed desktop dashboards mirror the same pattern: enodia-sentinel gui (stdlib tkinter) and enodia-sentinel gui-qt ([qt] extra with PySide6). Both are read-only over detection state, share the GUI-free gui/model.py, and display response plans for review only.
  • IPS behavior is currently explicit workflow: posture hardening plus reviewed dry-run containment actions. There is no automatic inline blocking or silent host mutation yet.

Near-term open work:

  • Audited --apply response execution with tests and rollback notes.
  • Fixture or red-team drill coverage for every built-in SID, including event-only and future correlation SIDs.
  • More event sources and correlation across exec, network, persistence, FIM, and rootcheck signals.
  • Stable v1 schema IDs and compatibility tests for alerts, incidents, status, response plans, and response audit records.

Start with:

  • README.md for product overview and architecture.
  • docs/INDEX.md for the versioned documentation entry point.
  • docs/SPECIFICATION.md for the product model and acceptance criteria.
  • docs/ROADMAP.md for sequenced work.
  • docs/COMMAND_REFERENCE.md for CLI contracts.
  • docs/OPERATIONS.md and docs/RUNBOOKS.md for operator workflows.
  • docs/PACKAGING.md for package layout and distro install paths.
  • docs/THREAT_MODEL.md for security boundaries and non-goals.

Engineering Rules

  • Keep the daemon stdlib-only and useful without a dashboard, collector, or network.
  • Prefer read-only detection and dry-run response until schemas and audit logs are tested and documented.
  • Every new detector, rootcheck, response action, or event rule needs a stable sid, signature, classtype, tests, and operator documentation.
  • Do not add stealth, self-hiding, persistence tricks, or automatic destructive remediation.
  • Preserve the bash prototype/red-team harness as the behavioral oracle for core signatures.
  • If you add config keys, update config/enodia-sentinel.toml, README, and the relevant docs.
  • Multiple agent sessions may share this checkout. Before committing, check git status for uncommitted edits you did not make; never sweep foreign hunks into your commit (stage only your own changes) and never stash or revert them.

Current Architecture

  • enodia_sentinel/cli.py is the command entry point.
  • daemon.py runs sweep/cooldown/background tasks.
  • system.py builds one cached injectable view of processes and sockets.
  • detectors/ contains pure poll detectors.
  • events/ contains optional eBPF exec/syscall monitoring plus declarative exec, syscall, and typed host-event rules.
  • snapshot.py writes forensic .log and .json evidence.
  • incident.py groups snapshots by process lineage and time window.
  • respond.py builds read-only response plans from incident evidence; the CLI persists reviewed dry-run plans under response-plans/ and appends response-audit.log, while dashboard/API previews stay write-free.
  • web.py serves the HTTPS-only management console and JSON APIs.
  • rootcheck.py performs anti-rootkit cross-view checks: hidden processes, processes hidden from ps, hidden modules, hidden TCP/UDP/raw/special-protocol sockets, raw ICMP/SCTP-style channels, promiscuous interfaces, known LKM rootkit module names, and kernel/module taint.
  • posture.py performs advisory host hygiene checks.
  • reconcile.py owns the acknowledged-drift store and the filter_alerts chokepoint that suppresses operator-accepted FIM/package/listener/SUID drift.
  • tray/ is the optional desktop tray frontend over the CLI and systemctl; only tray/app.py may import pystray/PIL (enforced by an import-guard test).
  • gui/ is the optional windowed desktop dashboard. gui/model.py is the GUI-free presentation model over tui.collect_model; only gui/app.py (tkinter) and gui/qt_app.py (PySide6, [qt] extra) import GUI libraries, enforced by import-guard tests.
  • go-agent/ is the isolated sidecar with Go config, process-state, detector, schema, and sweep-loop packages, plus fim/, pkgdb/, and rootcheck/ sidecar-only integrity engines. It writes JSONL to stdout (or a private retained tree under --state-dir) and must not share or mutate Python daemon state during parity development.

Current Threat Mapping

Recent local sample families used for defensive coverage:

  • Gonzalo-style implant/rootkit behavior: direct input-event keylogging, credential harvesting, LD_PRELOAD/tool tampering, persistence writes, raw ICMP and SCTP-style knock/listener paths, deleted/fileless execution, and hidden sockets/modules, plus heap/string obfuscation and mapped process-hiding libraries.
  • Peopleswar-style C2 behavior: TLS C2 listener/check-in traffic, command queue responses, and API/listener ports. Sentinel should prefer behavior coverage (new_listener, egress, stealth_network, memory_obfuscation, rootcheck, credential/input detectors) over brittle sample-name matching unless adding explicit IOCs.

Development Commands

python3 -m unittest discover -s tests -v
python3 -m enodia_sentinel.cli check
python3 -m enodia_sentinel.cli rootcheck
python3 -m enodia_sentinel.cli posture check --json
python3 -m enodia_sentinel.cli incident list
python3 -m enodia_sentinel.cli respond plan <incident-id> --json
python3 -m enodia_sentinel.cli rules list
python3 -m enodia_sentinel.cli web
make test-go
make parity-go

The web dashboard is HTTPS-only. In development it auto-generates a self-signed certificate under log_dir; tests use an unverified TLS context for that local certificate.

Testing Notes

  • Unit tests are stdlib unittest; pytest is optional, not required.
  • Most detectors are pure functions over injectable SystemState.
  • Rootcheck tests monkeypatch system views instead of depending on live /proc, /sys, or ss.
  • Web tests bind a local HTTPS socket and may require permission in sandboxed environments.
  • Go tests need a writable build cache; repo targets use GOCACHE=/tmp/enodia-go-cache for sandbox-safe verification.
  • Run the full suite before committing:
python3 -m unittest discover -s tests -v

Documentation Checklist

When changing behavior, update the relevant set:

  • README.md for visible product/architecture behavior.
  • docs/COMMAND_REFERENCE.md for CLI/API-visible commands.
  • docs/OPERATIONS.md for routine operator workflow.
  • docs/RUNBOOKS.md for alert response guidance.
  • docs/SPECIFICATION.md for product/data-model changes.
  • docs/THREAT_MODEL.md for trust-boundary/security-model changes.
  • docs/ROADMAP.md for planned or completed roadmap movement.
  • docs/SCHEMAS.md for stable JSON contracts.
  • docs/PACKAGING.md for package/install behavior.
  • packaging/release-artifacts.sh for release tarballs, checksums, and optional GPG signatures.
  • docs/VERSION.json and docs/INDEX.md for documentation versioning.
  • config/enodia-sentinel.toml for config knobs.