Skip to content

Auto-actions

An "auto-action" is something the AnalystAgent executes without a human in the loop during an investigation. By design, this list is very short — Fenrir is conservative on this for good reasons.

The single rule

The agent may auto-execute a tool only when all four of these are true:

  1. The tool is in the low-risk auto-action allowlist (defined in analyst.py).
  2. The investigation verdict is confirmed_threat.
  3. Confidence clears the auto-action threshold.
  4. The playbook explicitly listed this action under auto_actions_suggested in its final-report JSON.

If any of these fail, the action goes into recommended_actions and a human reads and decides.

The confidence threshold is configurable — see the Hardening checklist for production-grade values.

What's currently auto-executable

The allowlist today is deliberately minimal: only IP banning via fail2ban. It's reversible (unban_ip), affects no data, stops no service, and even a wrong ban costs the operator a few seconds to undo.

Anything else — firewall changes, service restarts, package updates, file modifications — stays human-gated. The agent can propose those actions in recommended_actions, but the operator (you) has to act on them.

Why it's so restrictive

We've all seen the demos where "the AI Security Engineer automatically remediates the threat." Then someone watches it for a while and finds out the AI:

  • Killed a legitimate service that just happened to spike CPU.
  • Banned an IP that turned out to be the customer's headquarters.
  • Rotated a credential that broke the production deployment pipeline.
  • Removed a setuid bit on a binary the operator needed to investigate first.

Each of those failures is recoverable. Most are very expensive to recover from. The ratio of "saved a few minutes" to "broke production for an hour" is not in your favor.

So: Fenrir does the conservative version. Bans an IP — fine, banning a wrong IP costs the operator 30 seconds to unban. Anything else stays as a recommendation.

What's NOT in the allowlist

  • block_ip_firewall — adds a permanent UFW rule. Heavier than fail2ban, harder to roll back.
  • Restart any service.
  • Apply package updates.
  • Modify any file owned by another user.
  • Anything in tools.py marked dangerous: True.

These are all callable by the agent in the interactive Telegram bot (where a human approves each call), but never in the autonomous investigation flow.

How it shows up in the report

Look at investigation_reports.auto_actions_taken:

[
  {
    "tool": "ban_ip",
    "args": {"ip": "1.2.3.4", "jail": "nginx-honeypot"},
    "result": "OK: 1.2.3.4 banned in nginx-honeypot",
    "executed_at": "2026-05-03T14:32:11Z"
  }
]

For audit purposes, this is the canonical record: every auto-action is preserved with its tool name, arguments, output, and timestamp. The full LLM transcript that led to the decision is also saved in raw_llm_output.

Tuning the threshold

The confidence threshold lives in analyst.py and is tunable. Lowering it makes Fenrir act faster but bans more clean IPs briefly. Raising it makes the agent more conservative — almost always correct, but more events go to the human queue.

If banning a wrong IP is very costly in your environment (you don't control your customer base's IP space, or one false ban means a phone call from a CXO), use the higher production-grade value — see the Hardening checklist.

Future expansion

A short list of things that may move into LOW_RISK_AUTO_TOOLS in future versions:

  • quarantine_setuid (just chmod -s, reversible) — under consideration.
  • rate_limit_ip (nginx limit_req) — needs nginx integration first.
  • notify_breach (auto-create GDPR breach record on confirmed_threat with severity CRITICAL) — likely in 0.6.x.

Anything more aggressive will stay human-gated. We'll never put kill_process or disable_user in the allowlist.