Skip to content

v0.15.30

Latest

Choose a tag to compare

@github-actions github-actions released this 28 Jun 07:58
· 4 commits to main since this release
79da12c

InnerWarden 0.15.30

Added

  • The agent-guard command inspector now flags attempts to disable InnerWarden itself (in-path self-protection). The check-command brain (POST /api/agent/check-command, the MCP innerwarden_check_command tool, and the agent proxy guard) previously scored commands like systemctl stop innerwarden-*, pkill -f innerwarden, innerwarden uninstall, and rm/truncate of InnerWarden's own binaries, config, data, or pinned eBPF objects as allow / risk 0 - so an AI coding agent wired through the in-path guardrail could be talked into turning the monitor off without the guard objecting. A new security_tooling_tamper signal (score 60 -> deny) in crates/agent-guard (threats::check_security_tamper + SECURITY_TAMPER_INDICATORS / INNERWARDEN_SELF_PATHS) now denies InnerWarden self-disable/removal plus the universal defense-evasion verbs (systemctl stop auditd, setenforce 0, auditctl -e 0, disabling AppArmor; MITRE T1562/T1489). File removal requires a destructive verb AND an InnerWarden path, so status reads and restarts (innerwarden get status, systemctl status/restart innerwarden-agent, grepping a config under /etc/innerwarden) are NOT flagged. Closes the command-layer half of the self-tamper gap surfaced by the 2026-06-27 AI-coding-agent guardrail evaluation (the kernel-side mitre_hunt uid-0 self-stop carve-out is tracked separately). New unit tests pin deny on the tamper set, deny on the host-monitor set, and allow on the benign reads/restart.
  • innerwarden agent install-hook wires the in-path command guard into Claude Code (enforcing, not advisory). agent mcp-serve and POST /api/agent/check-command are advisory - a coding agent running its raw shell tool never asks. The new command writes a fail-closed guard script plus a PreToolUse Bash hook into the agent's settings.json (~/.claude/settings.json by default; --settings/--url/--block-review override), so every shell command the agent proposes is POSTed to the loopback check-command brain and blocked (exit 2) before it runs when the verdict is deny (or review with --block-review), failing CLOSED if the agent is unreachable. The settings merge is idempotent and preserves existing keys/hooks. Currently supports Claude Code. Unit-tested: the JSON merge (empty / idempotent / preserves existing / repairs a non-object root) and the generated script (deny-only vs block-review, the check-command call, fail-closed on error).

Fixed

  • The admin-action audit log was stamped with local time, drifting off the UTC date scheme. append_admin_action named admin-actions-<date>.jsonl from chrono::Local::now(), while every other date-stamped file InnerWarden writes (events-/incidents-/decisions-*.jsonl) and the reader (today_date_string) use UTC. In a non-UTC timezone straddling midnight (e.g. UK/BST after 00:00 local, still the previous UTC day) the audit entry landed on a different date than the rest of the system, splitting the day's audit trail and breaking the reader plus the cmd_tune audit test on that boundary. Now UTC, consistent with the rest of the date-stamped files.
  • The correlation-chain block path bypassed the cloud safelist and banned Canonical on Hetzner (cloud-FP sweep follow-up). Two sibling response paths gate a candidate IP against the cloud/CDN safelist before escalating: the repeat-offender path and the completed-correlation-chain path. The repeat-offender path was switched from identify_provider (a first-octet heuristic that only knows a handful of broad ranges) to cloud_safelist::safelist_label (the real CIDR walk) on 2026-05-08, but the chain path was missed and still used the heuristic. Result: the Data Exfiltration (eBPF Sequence) chain (CL-008-class) banned Canonical 185.125.190.49 (apt/livepatch) on Hetzner, because 185.125.188.0/22 is in the safelist's CIDR table but the first-octet heuristic does not know 185.x. Both paths now route through one shared safelisted_provider helper (a thin wrapper over safelist_label), so the gate cannot drift between them again. Anti-evasion preserved: the safelist is the existing CIDR table (no new IP hardcoded), and a real attacker IP outside every safelist range (203.0.113.45, 45.148.10.121) is still blockable by both paths. A new #[tokio::test] drives both async paths end-to-end with a CIDR-only safelisted IP and asserts each purges it from reputation state instead of escalating.

Install / upgrade (Linux, toolchain-free, signed binaries)

curl -fsSL https://innerwarden.com/install | sudo bash
# already installed:  sudo innerwarden upgrade --yes

Every binary below is signed (Ed25519 + Sigstore bundle). Docs: https://github.com/InnerWarden/innerwarden/wiki · Site: https://www.innerwarden.com

What's Changed

  • fix(agent): correlation-chain block path bypassed cloud_safelist (banned Canonical) by @maiconburn in #1125
  • docs(changelog): record #1125 correlation-chain safelist-bypass under Unreleased by @maiconburn in #1126
  • feat(agent-guard): deny commands that disable InnerWarden itself by @maiconburn in #1127
  • fix(core): stamp admin-action audit filename in UTC, not local time by @maiconburn in #1128
  • feat(ctl): innerwarden agent install-hook — enforce the guard in Claude Code by @maiconburn in #1129
  • release: 0.15.30 — AI-agent guardrail self-protection + audit UTC fix by @maiconburn in #1132

Full Changelog: v0.15.29...v0.15.30