Why did we open-source our inference engine? Read the post
← All Posts

A hijacked AI agent still has valid credentials. Check its behavior instead.

A hijacked AI agent still has valid credentials. Check its behavior instead.

This article walks through agent-action-monitor, a workable example from the open-source SIE repo on GitHub: a behavioral security gate that screens AI agent actions before they reach downstream systems. SIE is Superlinked’s self-hosted inference engine, one cluster that serves embedding, reranking, OCR, vision, entity-extraction, and generation models behind three primitives (extract, encode, score). The example is a complete project; clone it and it runs end to end with Docker. It was built by Ritik Sah and Tanvir Farhad (PR #209).

Your AI agent just asked to open a firewall rule to 0.0.0.0/0. It has the right API key. It has the right permissions. Every credential check passes. And it has never once, in its entire operational history, touched a firewall rule.

Do you let it through?

This is the blind spot in most agent security thinking. Prompt injection, tool poisoning, a compromised dependency, a malicious MCP server: all of them produce the same end state, an agent with legitimate access doing something it was never meant to do. Permission systems can’t help you here. The attacker isn’t breaking in through the credentials; the credentials are working exactly as designed. What has changed is the behavior.

DUSK, an example project in the SIE repo, takes the position that the agent’s own history is the security boundary. It sits between an agent and its downstream systems as a gate. Every proposed action gets judged against that specific agent’s learned baseline, in real time, before it reaches anything that matters. An agent that has spent weeks reading logs and restarting pods suddenly wants to modify network rules? That’s not a permissions question. That’s an anomaly.

How the gate works

The architecture is small. A Flask service exposes a single /v1/gate HTTP endpoint. Agents (or the harness pretending to be agents) POST proposed actions to it. The gate compares each action against the agent’s baseline and returns one of three verdicts: ALLOW, WOULD-BLOCK, or BLOCK.

The judgment itself runs on three models served from one self-hosted SIE container. BAAI/bge-m3 (568M parameters) embeds the proposed action so it can be compared semantically against the baseline, BAAI/bge-reranker-v2-m3 (568M parameters) scores how well the action fits the agent’s normal pattern, and urchade/gliner_multi-v2.1 (289M parameters) runs zero-shot NER to flag privileged terms like credentials, network ranges, and destructive verbs. Encode, score, and extract, all behind one client. No stitching together three vendor APIs with three billing dashboards and three failure modes.

Verdicts trigger n8n webhooks for decisions, reports, and alerts, so the gate plugs into whatever incident workflow you already run. Nothing about the pattern is n8n-specific; the webhooks are just the demo’s stand-in for your paging and ticketing.

The baseline itself is the interesting asset. It’s a record of what this agent normally does, expressed as actions the models can compare against semantically. A new action doesn’t need to match a baseline entry verbatim; restarting a different pod still looks like pod restarts. Opening the firewall to the world looks like nothing the agent has ever done, and that distance is the signal.

There are two operational modes, and the distinction matters for adoption. Watch mode (the default) flags anomalies as WOULD-BLOCK but lets everything through; you get the signal without the risk of the gate breaking a legitimate workflow on day one. Once you trust the baseline, you flip to enforce mode and flagged actions actually stop before reaching downstream systems. This is the same rollout pattern as a WAF: observe first, enforce second.

What the numbers look like

The repo ships 15 baseline actions in sample-data/baseline.json, and sample-data/check-mixed.json adds 3 out-of-pattern attacks on top of that same baseline (18 actions, about 17% poisoned). Against the mixed fixture, the gate caught 100% of poisoned actions with zero false positives on the 15 clean baseline actions.

Latency is a separate full-stack run (20 requests per concurrency level, 20% poisoned), and it’s the number everyone asks about because a gate that adds seconds to every agent action is a gate that gets removed. At concurrency 5, p50 was 295ms and p95 was 317ms. At concurrency 1 the p50 was similar (294ms) though the cold-start p95 stretched to ten seconds while models warmed. For a control-plane action check (not a hot path, not a per-token cost), sub-350ms is the kind of overhead security teams can actually defend.

Running it

Everything comes up with one command:

docker compose up

That starts the gate, the SIE inference container, the n8n webhooks, a dummy downstream target, and an agent harness on an internal network. First run pulls about 5.7GB of model weights; give Docker at least 8GB. If you’d rather run pieces by hand, pip install -e . && python -m dusk.api gets you the gate service directly.

Then you replay the sample data, watch clean actions sail through, and watch the firewall-rule attack get caught by an agent baseline that has never seen anything like it.

Why this pattern is worth your time

Agent security is mostly being discussed at the prompt layer right now: better system prompts, input sanitization, injection detection. Useful, but all of it happens before the agent decides what to do. DUSK operates after the decision and before the consequence, which is the only place a behavioral check can live. It doesn’t need to know how the agent was compromised. It only needs to know that this action, from this agent, doesn’t fit.

The whole thing is a few hundred lines of gate logic plus one inference container. Clone it, run the compose file, and try to sneak an action past it.

Try it on GitHub: superlinked/sie/examples/agent-action-monitor

Open source inference for agents

Open-source inference for the models behind your agents. Run it yourself, or let us run it for you.

Github 2.7K

Contact us

Tell us about your use case and we'll get back to you shortly.

Apply for an inference grant

Free capacity on our hosted cluster for selected projects. Tell us what you run and we reply by email.