v0.9.5: CLI restructure, operator protection, notification fixes#75
Merged
Conversation
feat: AlphaZero defender brain + correlation rules + IP fix
Bumps [redis](https://github.com/redis-rs/redis-rs) from 1.1.0 to 1.2.0. - [Release notes](https://github.com/redis-rs/redis-rs/releases) - [Commits](redis-rs/redis-rs@redis-1.1.0...redis-1.2.0) --- updated-dependencies: - dependency-name: redis dependency-version: 1.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [redb](https://github.com/cberner/redb) from 3.1.1 to 4.0.0. - [Release notes](https://github.com/cberner/redb/releases) - [Changelog](https://github.com/cberner/redb/blob/master/CHANGELOG.md) - [Commits](cberner/redb@v3.1.1...v4.0.0) --- updated-dependencies: - dependency-name: redb dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.183 to 0.2.184. - [Release notes](https://github.com/rust-lang/libc/releases) - [Changelog](https://github.com/rust-lang/libc/blob/0.2.184/CHANGELOG.md) - [Commits](rust-lang/libc@0.2.183...0.2.184) --- updated-dependencies: - dependency-name: libc dependency-version: 0.2.184 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…son table - Rewrite hero section: emotional tagline, 2AM scenario, install CTA upfront - Add comparison table vs Falco/Wazuh/CrowdSec - Add "Who is this for" with 4 clear personas - Add "Why this exists" personal story + star CTA - Add Contributing section linking good-first-issue and help-wanted labels - Fix correlation rules: 30 → 40 (actual count from correlation_engine.rs) - Fix collectors: 20 → 22 (actual count from collectors/) - Fix eBPF hooks: 38 → 40 (consistent with badge) - Fix test count badge: 1943 → 1482 (actual #[test] count) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The no_alert_for_clean_login_nonpriv test used Utc::now() which fails when CI runs during off-hours (22:00-06:00 UTC) because the off-hours detection triggers for new IPs regardless of user privilege level. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
chore(deps): bump redis from 1.1.0 to 1.2.0
…-4.0.0 # Conflicts: # crates/agent/Cargo.toml
chore(deps): bump redb from 3.1.1 to 4.0.0
Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.26.7 to 0.26.8. - [Release notes](https://github.com/tree-sitter/tree-sitter/releases) - [Commits](tree-sitter/tree-sitter@v0.26.7...v0.26.8) --- updated-dependencies: - dependency-name: tree-sitter dependency-version: 0.26.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [fancy-regex](https://github.com/fancy-regex/fancy-regex) from 0.14.0 to 0.17.0. - [Release notes](https://github.com/fancy-regex/fancy-regex/releases) - [Changelog](https://github.com/fancy-regex/fancy-regex/blob/main/CHANGELOG.md) - [Commits](fancy-regex/fancy-regex@0.14.0...0.17.0) --- updated-dependencies: - dependency-name: fancy-regex dependency-version: 0.17.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
chore(deps): bump libc from 0.2.183 to 0.2.184
…0.26.8 chore(deps): bump tree-sitter from 0.26.7 to 0.26.8
…0.17.0 chore(deps): bump fancy-regex from 0.14.0 to 0.17.0
…rhaul Migrate SMM, hypervisor, killchain, and DNA from standalone repos into the main workspace as library crates. Integrate each inline into the agent event loop, eliminating 4 separate daemons and Redis dependency. Satellite migrations: - crates/smm/: Ring -2 firmware/UEFI/SMM audit (was innerwarden-smm) - crates/hypervisor/: Ring -1 VM detection, KVM monitoring (was innerwarden-hypervisor) - crates/killchain/: 8 bitmask attack patterns, PID tracking (was innerwarden-killchain) - crates/dna/: behavioral fingerprinting, anomaly detection, MITRE chain (was innerwarden-dna) Agent integration: - hypervisor_tick.rs: periodic audit, env caching, Blue Pill detection - killchain_inline.rs: real-time event processing through PidTracker - dna_inline.rs: behavioral sequences, fingerprinting, anomaly detection - firmware_tick.rs: now uses cached hypervisor env for VM detection - correlation_engine: Layer::Hypervisor + 3 new rules (CL-041/042/043) - Config: [hypervisor], [killchain], [dna] TOML sections Dashboard fixes: - Add esc() HTML sanitization function (XSS prevention) - Add toast() notification helper - Add --dim CSS variable (57 references were undefined) - Bump --muted/--warn/--orange contrast for WCAG compliance - Add /api/deep-security endpoint with DeepSecuritySnapshot - Add Deep Security cards to Health tab (firmware/hypervisor/killchain/DNA) - Fix Brain tab empty state message and responsive KPI grid - Make logo clickable (returns to Sensors home) - Add aria-labels to all navigation buttons - Fix silent error catches in loadReportDates and loadTopAction Server: 5 services consolidated into 1, Redis eliminated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Deep Security inline script contained </script> inside a JS template literal, which the HTML parser interpreted as closing the main script block — breaking all dashboard JavaScript. Fix: move deep security data loading to a proper loadDeepSecurity() function called after renderStatus() sets innerHTML. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The original esc() already existed as a const arrow function. The added function declaration caused SyntaxError: Identifier 'esc' has already been declared. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The insecure_http check blocked all actions (block-ip, suspend-user, honeypot) when the dashboard was exposed over HTTP on a non-localhost address. This prevented operation in common deployments where TLS is not yet configured but Basic Auth is active. Changed from hard-block to warning log. Authentication still required for all action endpoints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a trusted_user (from config) logs in via SSH, the agent automatically whitelists their source IP. Any AI-initiated block decision for that IP is vetoed with a log message. This prevents the agent from locking operators out of their own server when the neural anomaly detector flags their SSH connections. - Detect ssh.login_success events from trusted_users in event loop - Seed operator IPs from `who -i` on startup - Check operator_ips in execute_block_ip_decision before blocking - Also: allow dashboard actions over HTTP when auth is configured (insecure_http check changed from hard-block to warning) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of checking trusted_users list, detect any SSH login using publickey method as an operator session. This works across all Linux distros and users without config changes — having the private key proves operator identity. Also fixed event kind matching: sensor emits ssh.login_success with details.ip (not auth.login_success with details.src_ip). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dules feat: consolidate satellite modules + dashboard UX overhaul
Fixes CI clippy failure (-D warnings treats unused imports as errors). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The AlphaZero defender brain and neural anomaly engine are now purely observational. They log suggestions to brain-log.json for operator review in the Brain dashboard tab, but never trigger IP blocks or Telegram notifications. This prevents the neural model (which is still learning) from causing false-positive blocks that lock operators out of their own servers. Rule-based detectors (ssh_bruteforce, port_scan, etc.) continue to block threats normally. Changes: - incident_flow.rs: neural_anomaly and host_drift skip the AI gate entirely (no AI call, no block decision, no action execution) - notification_pipeline.rs: neural_anomaly and host_drift excluded from immediate threat notifications (even at Critical severity) - killchain tracker.rs: fix Duration import for tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major changes: - Migrate SMM, hypervisor, killchain, DNA into workspace crates - Integrate all 4 inline in agent event loop (eliminates 4 daemons + Redis) - Neural model advisory-only: observes but never blocks or notifies - Operator IP protection via SSH publickey detection - Dashboard: Deep Security cards, XSS fix, contrast/accessibility - Allow dashboard actions over HTTP with auth configured - 43 correlation rules (3 new hypervisor rules: CL-041/042/043) Server: 7 processes → 3, Redis eliminated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove RUSTSEC-2026-0074 ignore (no longer in dependency tree) - Change killchain/dna license from Proprietary to BUSL-1.1 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add comprehensive clippy allows for migrated crates (smm, hypervisor, dna) to handle newer Rust 1.94 lints (manual_swap, collapsible_if, etc.) - Update russh from yanked 0.58.1 to latest patch - All crates now use BUSL-1.1 license (workspace standard) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gnore russh 0.58.0 still depends on vulnerable libcrux-sha3 — re-add the advisory ignore since it doesn't affect our SSH usage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…visory Migrated crates (smm, hypervisor, killchain, dna) use clippy::all to avoid chasing individual lints across Rust versions. These crates will be cleaned up incrementally. RUSTSEC-2024-0384 (notify unmaintained) ignored — only used by DNA daemon binary, not the library consumed by the agent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CPUID clobbers ebx which LLVM reserves for its own use. Save/restore rbx manually around the CPUID instruction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- correlation_engine: remove duplicate Userspace branch (identical blocks) - hypervisor_tick: use function pointer instead of closure for spawn_blocking - hypervisor_tick: use matches! macro instead of match - dna_inline: use slice::from_ref instead of clone in single-element array Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OpenClaw upstream has a TypeScript duplicate declaration bug (ConfigAuditAppendParams). Mark the openclaw image build as continue-on-error so it doesn't block the InnerWarden release. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The public live-feed was returning 295 incidents but only 2 had IPs. The rest were internal noise (host_drift 847, network_sniffing 93, sigma 52, etc.) with no external attacker. Now filters out: - Advisory-only detectors (neural_anomaly, host_drift, network_sniffing, discovery_burst) - Any incident without an external IP in entities - System daemon false positives The website attack map now shows only real attacks with geolocatable IPs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously only read today's file, which could show near-zero data early in the day or after a quiet period. Now reads both today and yesterday, filtering to the last 24 hours. Result: 45 events, 36 blocked, 40 unique sources (vs 1 before). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…bool> Clap panicked with type mismatch when parsing --dry-run flag because the field was Option<String> but the handler expected Option<bool>. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three auto-block gates (obvious incident, AbuseIPDB, CrowdSec) could block operator IPs despite being in trusted_ips allowlist. The normal AI decision path had the check but these fast-path gates bypassed it. Changes: - Seed operator_ips with allowlist.trusted_ips at startup so trusted IPs are protected even before the first SSH login event is processed - Add explicit trusted/operator IP checks in all three auto-block gates as defense-in-depth alongside the existing check in decision_block_ip This prevents the critical scenario where the tool blocks its own operator, causing them to lose access to their server. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace static trusted_ips allowlist with dynamic session-based protection: - operator_ips is now HashMap<String, Instant> with session timestamps - Refresh active sessions from `who -i` every 30s in the slow loop - IPs are automatically removed when SSH sessions end - No more permanent IP protection that could shield future attackers - All 4 block paths check operator_ips: decision_block_ip, obvious gate, AbuseIPDB gate, CrowdSec gate This solves the dynamic IP problem: operators with changing IPs are protected only while actively connected, not forever. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reorganize the CLI around user intent instead of internal structure: get — Query status, incidents, decisions, reports, metrics stream — Real-time monitoring of incidents/events action — Manual response (block/unblock IPs) trust — Manage trusted IPs, users, suppressions config — AI, notifications, integrations, mesh (merges configure+notify+integrate+mesh) system — Diagnostics, hardening, tuning, data export module — Security module management (unchanged) agent — AI agent management (unchanged) Key improvements: - `innerwarden --help` shows only the 8 main commands - Typing a group without subcommand shows available options - All old commands still work as hidden aliases (backward compat) - No handler functions changed — only CLI structure and dispatch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. host_drift: add /lib/, /lib64/, /nix/store/ to trusted paths Systemd binaries in /lib/systemd/ were triggering 1500+ daily false positives. 2. neural_anomaly: raise threshold from 0.5 to 0.75 Spider Sense was firing 1000+ times/day at the old threshold. 3. Telegram: add hourly rate limit (30/hour) for automated alerts Budget check was only enforced in 1 of 14+ send paths. New send_alert_html() method enforces the cap globally. Bot command responses still use send_raw_html (no limit). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major UX and reliability improvements from today's session:
CLI Restructure (8 intent-based commands)
get,stream,action,trust,config,system,module,agentinnerwarden --helpshows only the 8 main commandsinnerwarden system)Operator IP Protection (critical bug fix)
who -i, expires when session endsNotification Spam Fix (3 sub-fixes)
/lib/,/lib64/,/nix/store/to trusted paths (was 1500+ false positives/day from systemd binaries)send_alert_html()with 30/hour global cap. Budget was only enforced in 1 of 14+ send paths. Now all automated alerts go through the rate limiter.CTL Bug Fix
innerwarden configure responder --dry-runcrashed with clap type mismatch (Option<String>→Option<bool>)Test plan
cargo checkpasses for all crates🤖 Generated with Claude Code