Your agent is about
to drop the database.

Invarix.Gate reads the arguments of every tool call before it runs and knows which ones cannot be undone. AI guardrails for agents you host yourself, on Microsoft.Extensions.AI or Microsoft Agent Framework, with a first run that changes nothing so you can see what it would have caught before you turn enforcement on.

$dotnet add package Invarix.Gate --prerelease
How it works Pricing
11
detectors in the default pack
Arguments
are what the rules read, not tool names
Observe
is the default, and blocks nothing
In process
no proxy, no model calls
What it flags

Rules drawn from
incidents that happened.

An agent wiped a production database during a code freeze. A compromised extension shipped a wiper prompt. In the incidents these rules distill, nothing was breached: something ordinary was allowed to run against the wrong target. Below are 7 of the 11 detectors in the default pack. The rest cover mass sends, tools outside an agent's declared allowlist, call and token ceilings, and an agent editing Gate's own policy, the one with no public incident behind it yet. The everyday commands that resemble all of these are tested just as hard.

01

Destructive SQL

DROP, TRUNCATE, and DELETE or UPDATE with no WHERE clause. A lexer strips string literals and comments first, so a DROP quoted inside a value cannot trip it and a scoped delete never does. Replit's agent wiped SaaStr's production database during a code freeze in July 2025.

02

Shell and file destruction

rm -rf outside the workspace, del /s, Remove-Item -Recurse -Force, mass deletes. Compound commands split on every separator, so a destructive tail after a harmless head still fires. The compromised Amazon Q extension shipped a wiper prompt that only a syntax error stopped.

03

Git history destruction

Force pushes, branch deletes, and filter-branch on the branches you protect. A force push to the agent's own feature branch is a routine rebase and stays quiet, because a rule that blocks that gets uninstalled the same afternoon.

04

Cloud teardown

delete-stack, terminate-instances, terraform destroy, namespace deletes, across the AWS, Azure, and GCP spellings including the s3api forms. kubectl delete pod never fires, because the workload is self healing.

05

Credential egress

Access keys, tokens, private keys, JWTs, and connection strings heading out of the building. Scoped to outbound tools only, so writing a key to a local file is not the same event as posting it. In enforce mode, the one rule that blocks outright rather than asking.

06

Runaway loops

Exact repetition, retry-with-jitter, and A-B-A-B ping-pong between two agents. In enforce mode a loop ends the run rather than losing a single call, because denying one call hands control straight back to the loop that made it.

07

Protected targets

The hosts, databases, paths, cloud accounts, and schemas you declared off limits, matched inside any argument of any tool after the command is resolved. Every other rule asks whether the operation is dangerous. This one asks what the call was pointed at, because in the destructions of 2026 the operation was ordinary and the target was not: a test URL that resolved to the production host, a production database passed as the disposable one, a home directory that expanded to the wrong root. Nothing is declared by default, because nobody can guess which host is yours.

Program.cs
using Invarix.Gate;
using Microsoft.Extensions.AI;

// Observe mode is the default. Nothing is blocked, everything is reported.
var gate = GateEngine.Create(GateOptions.FromYaml("gate-policy.yaml"));

// Any Microsoft.Extensions.AI pipeline. MCP tools are covered here too,
// because an MCP client tool is an ordinary AIFunction.
var client = inner.AsBuilder()
    .UseInvarixGate(gate, agentId: "checkout-bot")
    .Build();
Past the tool name

Where a name match
runs out.

Allowing and denying on the name of a tool is the cheap part of agent governance, and there are free ways to do it in .NET. It settles the easy cases. What it cannot settle is what the call was pointed at, how much the run has already spent, who said yes, and what an auditor can still read a year later.

01

The argument, not the verb

In the incidents behind these rules the tool was one the agent was allowed to call, and the damage was in the argument it was given. Gate parses arguments before the call runs: SQL through a lexer that drops string literals and comments first, shell commands split on every separator, git invocations resolved to the branch they would rewrite, outbound bodies read for access keys, tokens, and connection strings.

02

Ceilings checked before the call

Ceilings on tool calls and tokens, per run and per agent across runs, evaluated in your process while the next call is still a proposal. A per run ceiling on its own does not hold, because a host that mints a fresh run id for every request resets the budget each time. The pair of agents that looped for 11 days and $47,000 did it across many runs, and an invoice is where you find out about that afterwards.

03

Human in the loop approval

An escalated call is held while a redacted request goes to an endpoint you host. An operator opens the page, reads what the agent is asking to do, and answers. A GET only renders, so a mail scanner or a chat preview that fetches the link cannot decide anything. The POST decides, and it decides once: the token carries 256 bits of entropy, is stored only as a SHA-256 hash, and is consumed on use.

04

Evidence that outlives the process

Wire the Evidence bridge and every verdict becomes a CloudEvents 1.0 record carrying the tool that was asked for, the SHA-256 digest of the exact arguments, each rule that matched, and the operator who approved or refused. Batches seal into Merkle trees under your own Ed25519 key, and an auditor verifies a proof offline from one JSON file and your public key. Retention policies, legal holds, and signed deletion certificates ship with it.

From install to enforce

It reports first.
You decide when it acts.

Start with where Gate can act, because that settles whether the rest of this page applies to your agent. Inside that boundary, observe mode is the default and blocks nothing, so the first thing you get is a report of what your agent has been doing.

Where enforcement reaches

Gate decides these before they run

  • Agents you host in your own process, wired through the Microsoft.Extensions.AI or Microsoft Agent Framework adapter.
  • MCP client tools, which arrive on that same pipeline as ordinary functions.
  • On premise and self hosted deployments, including ones with no outbound network at all.

Gate cannot stop these

  • Agents hosted inside Azure AI Foundry Agent Service or Microsoft Copilot Studio. The tool executes inside the provider's service, where nothing in your process gets a turn first.
  • A call that reaches the framework on a path around the adapter. Gate detects it where the framework reports it and the coverage block counts it, by which time the call has run.
first run, observe mode
── Invarix.Gate ── observe mode ── run sample… ── agent release-agent ──
  15 tool calls evaluated · 0 blocked (observe mode never blocks)
  In enforce mode, this run would have seen:

  IRREVERSIBLE (would require approval)             3 calls
    destructive-sql   db_execute      DELETE without WHERE in statement 1
    git-history       run_command     git push --force rewrites the protected branch…
    scope-allowlist   publish_release Tool "publish_release" is not in the allowlist…

  HIGH-CONFIDENCE (would block)                     1 call
    secret-egress     http_post       AWS access key id in outbound argument "body"

  CUMULATIVE (would warn / terminate)
    limits.calls      15 / 300 tool calls (5%)
    runaway-loops     poll_job_status called 6 times with identical arguments…

  COVERAGE (within the wrapped pipeline)
    7 tools registered · 7 routed through Gate · 0 calls observed outside Gate

  SUGGESTED NEXT STEPS (policy edits and diagnostics)
    add "poll_job_status" to limits.loops.exempt if this tool is expected to repeat…

  Flip to enforce: set `mode: enforce` in gate-policy.yaml
Five things a call can be
  • allowRun it. Nearly every call ends here.
  • warnRun it, and put it in the report.
  • escalateHold it for a human to approve.
  • denyRefuse it, and tell the model why so it can adapt.
  • terminateRefuse it and end the run.

The most severe verdict across every matching rule wins, and there is no way to write a broad allow that quietly swallows a narrow deny. No policy can assign terminate. In enforce mode, the engine does it when a run hits a loop or a ceiling.

  1. 1

    Install and wire one line

    One package and one builder call on the chat client or the agent. Nothing else in your host changes, and the decision path sends no traffic anywhere.

  2. 2

    Run your agent as usual

    Observe mode evaluates every tool call and stops none of them, runaway loops included. Installing it cannot break a working agent.

  3. 3

    Read what it would have stopped

    The report groups findings the way Gate decides: irreversible, high confidence, and cumulative. It also names what it could not see, and names the exact policy keys to edit.

  4. 4

    Flip one line

    mode: enforce, on a license that covers your company. The same rules that reported now act: Gate denies the call with an explanation the model can read, holds it for a human to approve, or ends the run when a ceiling is breached.

Pricing

What it costs.

The free tier is the whole product, and the line between free and paid is your company's revenue rather than a feature list. Above the line it is one payment sized by the developers it covers, not a subscription that has to be defended at every renewal.

Community

€0
free under €1M in annual revenue

For companies under €1M in annual revenue. Nothing is held back for the paying tiers, so a two person shop runs the detectors and the enforcement a bank runs.

  • All 11 detectors, at their tuned defaults, protected targets included
  • Observe mode with no license key, and enforce mode on a token issued at no charge
  • Human approval for escalated calls, over HTTP
  • Evidence records via Invarix.Guard.Evidence
  • The run report, the verdict log, and coverage reporting
  • Policy in YAML or fluent C#
  • Adapters for Microsoft.Extensions.AI and Microsoft Agent Framework, as separate packages
  • No support of any kind, no SLA. The docs ship in the package
Install from NuGet ↗

Team

€1,500
one payment, up to 10 developers

For a company at or above €1M in annual revenue with 10 or fewer developers building against Gate.

  • Everything in Community, with no revenue limit
  • Up to 10 developers on the license
  • 12 months of updates from the date of purchase
  • On expiry, the last version you received keeps working. No kill switch, no phone home
  • Renewal is optional, at 35 to 40 percent for another 12 months
  • No support of any kind, no SLA. The docs ship in the package

Prices are in EUR, per company, with no VAT added. Every band sits under the Elastic License 2.0, which rules out offering Gate to third parties as a hosted or managed service. Revenue is measured on the group rather than on the entity that installs the package, and a company that crosses €1M moves to a paid band within 90 days of the end of that financial year. Shipping Gate inside a product you sell needs a redistribution license, quoted per product. Email sales@invarix.dk and describe what you are embedding it in.

FAQ

What to settle
before you install it.

Will this break my agent?
Not in observe mode, which is the default and blocks nothing, including runaway loops. That is deliberate. You can put it in production without a change management conversation. You install it, run your agent exactly as before, and read a report about what would have happened. Enforcement is a separate decision you make later, on one line, once you have seen the report and tuned anything that looked wrong.
Isn't this just a prompt telling the model to be careful?
No, and that distinction is the whole product. A prohibition in a prompt does not bind: the Replit agent deleted a production database during an explicit code freeze it had been told about in writing. Gate sits below the model, at the point where a tool call is about to execute, and it is deterministic: pattern matching, argument parsing, and counters, with no second model in the decision path. The same call with the same policy always gets the same verdict. You can test that. A reviewing model cannot promise it.
How much latency does it add?
Microseconds, not model calls. Verdicts are pure CPU work over strings and a small amount of run state, with no network, no inference, and nothing to warm up. Compare it with the alternative designs: a reviewing model costs a round trip and its own failure modes, and a network proxy cannot see inside your process at all. The one measurement so far: a median of 57 microseconds through the full default pack, p99 of 210 microseconds, over 20,000 evaluations on one developer machine. Every verdict carries its own ElapsedMicroseconds, so you can check the number on your hardware instead of taking ours.
What about false positives?
They are the reason a pack like this gets uninstalled, so they are tested harder than the catches. Roughly 80 of the 190-odd scenarios in the test corpus exist purely to prove ordinary work stays quiet: a DELETE with a WHERE clause, rm -rf node_modules inside your workspace, kubectl delete pod, a force push to your own feature branch, pagination that looks like a loop. A regression in any of them fails the build. Scoping does most of the work: the SQL detector never sees a code review tool's arguments, so SQL quoted in a diff cannot trip it.
What can it not see?
Deterministic matching has limits and they are written down. A command hidden behind shell variable expansion, an encoded payload, a symlink pointing out of the workspace. Those are in COVERAGE.md, and several are pinned as test cases so a change that starts catching one forces the documentation to be updated. The wider boundary is the coverage table above, which calls reach Gate at all, and every run report repeats that one as a count, including when the count is zero.
Why .NET, when everything else in this space is Python?
Because that is exactly the gap. The agent frameworks .NET teams are adopting are new and come from Microsoft itself, while the guardrail tooling around them assumes Python and assumes the cloud. Meanwhile many of the enterprises with the most to lose from an unsupervised agent run on .NET: banks, insurers, logistics, healthcare, government. A network proxy cannot see inside an air gapped process. This runs in the process and needs nothing but the runtime. The decision path makes no outbound calls, and the one optional outbound piece, the approval webhook, is a separate package posting to an endpoint you host.
Microsoft ships an agent governance toolkit. Why not use that?
You might, and for some teams it is the right call. A platform gives you policy, telemetry, and somewhere to administer all of it. Gate is one NuGet package with a narrower job, and what it does past matching on the tool name is set out above. The other difference is release behavior. Gate freezes its policy schema and its pack, so a new detector ships switched off in a minor release rather than changing what your build does overnight. If you want a platform, take theirs. If you want one package that judges dangerous calls and reports what it could not see, take this one.