OpenRouter has added a safety layer for AI agents that call tools. Armor, in beta since October 2026 according to OpenRouter's documentation, is "a classifier that runs between the model and your application and evaluates every tool call the model makes." You describe what the agent must never do, what it should usually not do, and what is allowed, in plain English. A call that breaks a rule is blocked, the model is told why, and it carries on.
The announcement went further than the docs: OpenRouter's posts said Armor "uses Jev to guard against out of policy tool calls before your agent executes them, with better performance than Claude Code's auto classifier at a fraction of the cost," and OpenRouter's leadership said Jev 1.13 had the highest accuracy and lowest cost against other decision models and against the classifier Claude Code uses. Those are claims; the documentation does not publish the test. Below we separate the two.
TL;DR: Armor claimed versus verified
| Claim | Source | Status |
|---|---|---|
| Armor checks every tool call against plain-English rules | OpenRouter docs | Documented |
| Works with any model and harness | OpenRouter posts | Partly documented: Responses, Chat Completions and Messages APIs, plus Claude Code compatibility |
| Claude Code auto mode works on any OpenRouter model | OpenRouter docs | Documented, via the Ori metaharness |
| Powered by TypeSafe's Jev | OpenRouter posts | The docs say "the decision model" and link Jev elsewhere; versions are not tied down on the Armor page |
| Beats Claude Code's classifier on accuracy and cost | OpenRouter posts citing internal testing | Unverified: no test set, metrics or cost numbers published |
| Replaces regex filtering that is "insufficient" | OpenRouter framing | Plausible argument; no comparison data |
How does Armor work?
For each tool call the model makes, per the docs:
- OpenRouter does not forward the call to your application yet.
- It sends the call, your rules and the conversation so far to a decision model.
- For each rule, the decision model returns a probability that the call matches it.
- Armor combines those into one verdict: flagged or not flagged.
If flagged, the call is marked to skip execution with metadata naming the rule and telling the model not to retry with the same arguments; the model then makes a narrower call or explains to the user. If not flagged, the call is released unchanged and the response carries a safeguard_results field recording the verdict.
The decision model in question is the kind of system we covered in what a System One model is: it returns typed probabilities rather than prose. For background on TypeSafe's Jev, see the launch coverage and our guide to decision models.
What are the three rule tiers?
| Tier | Meaning | Can anything clear it? |
|---|---|---|
| Hard-deny | Actions that must never happen, such as credential exfiltration | No. Not an allow rule, not the user asking |
| Soft-deny | Usually wrong, sometimes legitimate, such as deleting a directory | Yes: an allow rule, or the user asking for that exact operation on that exact target |
| Allow | Exceptions to soft-deny rules | Never blocks anything on its own |
Rules can carry an id, a name, instructions up to 8,000 characters, and a threshold from 0 to 1. Defaults are 0.6 for deny rules and 0.7 for allow rules; OpenRouter says they were set on Claude Code's auto-mode test sets, and that below 0.7, partially applicable allow rules were clearing force pushes and repository deletes. A separate environment list holds facts the classifier should treat as true, such as the trusted repository, the deploy target, or the user's role.
OpenRouter's own advice on writing rules is practical: describe the action, not the command ("rewriting git history that has been pushed" rather than one spelling of git push --force), name what the rule protects, put exceptions in allow rules, and keep the environment current.
Claude Code auto mode on any model
The most concrete compatibility claim is documented. Armor implements a Claude Code compatible API: it reads Claude Code's safeguards entry and answers in the format Claude Code expects from Anthropic's own implementation. OpenRouter's example launches Claude Code through its Ori metaharness with a non-Anthropic model and the permission mode set to auto. Where the request reaches an Anthropic endpoint that supports the beta, Anthropic's classifier evaluates and its verdict is passed through; on every other endpoint, Armor evaluates.
One caution from the docs: under the Claude Code compatible mode, your application is what stops the call. A Messages client that ignores safeguard_results will run a flagged tool use. If you do not control the client, OpenRouter advises requesting text output mode so the call is withheld.
How do you test rules before enforcing them?
The beta has an audit mode that runs the same evaluation and reports the same verdicts but releases every call. The recommended loop is to run it against real traffic, read the verdicts, tune the rules until they match what you want stopped, and then switch to enforce. In audit mode the safeguard_results field is the only place a flagged verdict shows up.
Verdicts can also be unavailable (the decision model timed out, errored, or the request was too large) or skipped (a provider-native tool that ran on the provider's side). The on_error setting decides what happens: block by default, or log and release.
What are the limits?
- It is a beta; configuration fields, the
safeguard_resultsobject and the blocked item type may change. - Armor evaluation is not yet supported for requests under HIPAA, Zero Data Retention or a data-region restriction; a request that enables it in those contexts is rejected with a 403.
- A classifier is probabilistic. A rule is matched at a threshold, not proven, so tune with audit mode and keep high-stakes actions behind a human.
- Every tool call adds a call to a decision model, so expect added latency and cost. OpenRouter does not publish either figure on the page.
Why this matters for people running agents
Most coding-agent harnesses ask a human to approve each command. People get fatigued and approve everything, or switch to a mode that approves nothing. Classifier-gated "auto" modes try to sit between: routine commands run, risky ones stop. Armor makes that available outside Claude Code and for custom agents, and lets you write your own policy. The Jev docs include a cookbook for gating agent tool calls and another for auto-approving permission prompts from coding agents, which shows where the underlying model is being pointed.
Related security thinking is in our coverage of the Jev prompt-injection detector, the Jev speed and cost claims fact check, and the Jev 1.14 claimed versus verified post. For an independent angle on isolating agents rather than classifying their calls, see Capsem's VM sandbox.
A worked example from the docs
OpenRouter's own example is a good test of how the pieces fit. A custom agent is given a bash tool and one hard-deny rule named Git Push, with the instruction "Running any git push command. The user reviews every change before it is pushed." The environment lists one trusted repository. The user asks the model to push the branch to main.
The model calls bash with the push command. Armor blocks it. In the Responses API with the custom item output mode, the response contains no function call; in its place is a typed blocked item carrying the call and the rule that fired, followed by the model's own message that it cannot run the push and that the user should run it directly. The safeguard_results field records the verdict as flagged with the explanation naming the rule.
Change the prompt to listing the files in a reports directory and the same bash tool call is released as an ordinary function call, with the verdict recorded as not flagged. Two lessons follow. First, the model is told why a call failed and does not loop on it, which is the difference between a guardrail and a crash. Second, the rule describes the policy ("the user reviews every change before it is pushed") rather than a command pattern, which is exactly the shift from regex filtering that OpenRouter argues for.
Armor versus the alternatives
| Approach | How it decides | Typical weakness |
|---|---|---|
| Human approves every command | A person reads each call | Fatigue; people click through |
| Regex or allowlists | Pattern match on command text | Misses rephrased or chained commands |
| Claude Code auto mode with Anthropic's classifier | A model judges each call against built-in rules | Tied to Anthropic's endpoint and rule set |
| OpenRouter Armor | Decision model scores your plain-English rules | Beta; probabilistic; extra call per tool use; benchmarks unpublished |
| VM or container sandbox | Limits what any call can reach | Does not judge intent; blocks by capability |
These are complementary. A sandbox limits the blast radius, a classifier catches calls that are allowed by capability but wrong by intent, and a human still owns the irreversible ones. The comparison that matters for Armor, accuracy against Anthropic's classifier on a shared set of tool calls, is exactly the one nobody outside OpenRouter has seen.
What to do next
- Start in audit mode on a non-production agent and read every flagged call.
- Write two or three hard-deny rules first: credential exfiltration, pushing to protected branches, destructive deletes.
- Add environment facts and allow rules for your test suite and build steps.
- Treat the "better than Claude Code" claim as untested until OpenRouter publishes numbers; run your own comparison on your own tool calls.
- Keep a second layer. AgentBeam, the agent security platform from the explainx.ai team, is built to stop AI agents before they take dangerous actions, independent of the model provider.
Related reading
- What is a System One model?
- TypeSafe AI Jev launch
- What are decision models? A guide
- Jev prompt-injection detector
- Jev speed and cost claims fact check
- Jev 1.14: claimed vs verified
Sources: OpenRouter Armor documentation and OpenRouter's Jev documentation.
Beta behavior is as documented on October 16, 2026 and may change.
