
SOC, incident response and SecOps for Linux servers in one agent: learns each host, watches it with zero-token sensors, triages with a small model, and contains attacks under a root-owned policy. Optional hub for fleets.
Hackers have agents that attack 24/7. Now you have one that defends.
The simulation from problem99.io/kodeblue: one kodeblue per server, containing attacks as they land.
An AI blue team for your Linux servers: SOC, incident response and SecOps in one. One kodeblue per server, running as its own non-root kodeblue user. It does the work of all three, and never sleeps:
It is built to run on a small, cheap model behind any OpenAI-compatible API: deterministic sensors and filters do the heavy lifting, so the model only sees what survives them. Without a model configured, sensors, detection and monitors still run.
fast watch (5s) ─► sensors (60s, 0 tokens) ─► deterministic filters (0 tokens) ─► triage (small model, batched)
+ agent-written monitors (0 tokens) │
▼
daily review session ◄─ reports/skills/monitors ◄─ one agent session per incident ─► respond (policy) ─► Slack
An optional hub (kodeblue-hub) gives a fleet one console: every server's incidents, reports, the agents' reasoning and tool calls (live), monitors, findings and pending approvals, and a way to message the agents. Servers only dial out to it, always over TLS (plain HTTP is allowed only to a hub on the same machine).
Each step is one command plus your model's API key, on Linux with systemd (amd64 or arm64; see Requirements). The installers download the latest release for the server's architecture and check it against the release's SHA256SUMS before installing. To download and check the files yourself, or to build them, see docs/deploy.md and Build.
curl -fsSL https://github.com/Problem99-io/kodeblue/releases/latest/download/install.sh | sudo sh -s -- --inference-url https://openrouter.ai/api --model <model>
Use any OpenAI-compatible endpoint, with or without /v1 at the end. The installer asks for its API key, an optional Slack webhook, and optional Telegram bot credentials (secret input is not echoed), and starts kodeblue. kodeblue takes snapshots of the server for about 30 minutes. A learning session then explores the server and an assessment records its vulnerabilities (each can take up to 45 minutes), so expect it to start watching within one to two hours.
Without --inference-url, kodeblue starts watching after the snapshots, and the learning session and assessment wait until you set a model; they then run on their own. Set or change the model, and its key, with one command (it asks for the key and restarts kodeblue):
sudo kodeblue inference --url https://openrouter.ai/api --model <model> --key-file -
Telegram notifications can be used alone or alongside Slack. Standalone servers configure them during installation; hub users configure Settings → Telegram. See Telegram setup for bot and chat-ID instructions.
Then review the policy (response mode, protected users, IPs and units, budget) with sudoedit /etc/kodeblue/kodeblue.toml, and follow along with sudo journalctl -fu kodeblue.
On the hub host, here with a self-signed certificate that servers pin:
curl -fsSL https://github.com/Problem99-io/kodeblue/releases/latest/download/install-hub.sh | sudo sh -s -- --public-url https://hub.example.com:8443 --self-signed
Or run the hub image: ghcr.io/problem99-io/kodeblue-hub:latest (see docs/deploy.md).
The installer asks for the first operator's password (twice) and starts the hub. Then:
f=$(mktemp) && r=$([ "$(id -u)" = 0 ] || echo sudo) && { curl -fsSL --proto =https --proto-redir =https -k --pinnedpubkey 'sha256//…' -o "$f" https://hub.example.com:8443/install.sh && echo "<sha256> $f" | sha256sum -c - && printf '%s\n' kbe_… | $r sh "$f" --hub https://hub.example.com:8443 --pin 'sha256//…' --token-file -; s=$?; rm -f "$f"; (exit "$s"); }
It saves the installer, checks its hash before running it as root, and passes the single-use token on stdin so it never appears in a process's arguments. The server takes the hub's model and key at enrollment and asks nothing. A server that has no model yet watches with its deterministic detection, and the hub shows that its learning is waiting for one.
For a hub on the internet, we recommend putting it behind Cloudflare with a cloudflared tunnel: the hub host opens no port, servers verify Cloudflare's public certificate (no pin), and Cloudflare Access can guard the console. Cloudflare then sees the traffic between servers and the hub; see docs/deploy.md for the setup and the trade-off.
To hide the console from everyone but your office or VPN, add --console-allow 203.0.113.7,10.66.0.0/24 (servers can still enroll and sync). For a real certificate, a reverse proxy, Docker or WireGuard, see docs/deploy.md and docs/hardening.md.