All comparisons

Microsoft Agent Governance Toolkit and Intercis

The Microsoft Agent Governance Toolkit is a library your agent imports. Intercis is a proxy your agent's base URL points at. That one difference sets most of the rows below, and it does not settle the choice: the toolkit is free, open source, speaks five languages and covers ground we do not touch. Five of the twelve rows below go to the toolkit.

Twelve things a security reviewer can check on both sides. Microsoft cells cite a repo path at commit 8f1d0e1. Intercis cells cite a live page or a file in our repository.
Intercis Microsoft Agent Governance Toolkit, from the repositoryRead 18 September 2026 from a local clone of github.com/microsoft/agent-governance-toolkit at commit 8f1d0e1, MIT licence. How to check
Where enforcement runs Out of the agent's process, in the path of the provider call. The agent's base URL points at us and the agent's code does not change. We govern Anthropic's POST /v1/messages and OpenAI's POST /v1/responses and POST /v1/chat/completions. Being in the path is a configuration setting, not a law: a process that can change its own base URL can call the provider directly, so pair us with an egress rule that blocks direct calls to the provider APIs. Without that rule we are a control a compromised process can walk around. In the agent's own process, with an out-of-process option that is still called by the application. README.md, "Security": "AGT enforces governance at the application middleware layer, not at the OS kernel level. The policy engine and agents share the same process boundary." docs/FAQ.md section 1 lists where it runs as "In-process middleware or sidecar alongside each agent". The sidecar is not transparent: docs/FAQ.md section 2 states "Transparent tool-call interception is not yet implemented in the sidecar. The agent or orchestration layer must call the sidecar API explicitly". Toolkit: read README.md under "Security", docs/FAQ.md sections 1 and 2. Intercis: intercis.io/limitations, first cost. Both costs are real and neither disappears by choosing the other product.
What happens on a deny The action is removed from the response rather than labelled in it. On a deny the proxy builds a synthetic provider-shaped reply: the model's tool_use block is gone, one assistant text block naming the policy is in its place, and stop_reason becomes end_turn. The agent runtime never receives a tool call, so it has nothing to execute. The three enforcement verdicts are allow, deny and observe. The toolkit returns a decision and the application carries it out. policy-engine/docs/security-model.md, "Trust Boundaries": "The host enforcement boundary lies after ACS returns a verdict. The host must block, transform, escalate, or proceed in accordance with the result." The same file lists "Compromised host application" in its threat table with the status "Out of scope" and the note "ACS returns decisions but cannot force malicious host code to obey them." In the Python quick start the deny surfaces as a GovernanceDenied exception raised inside the caller (README.md, "Quick Start"). Toolkit: policy-engine/docs/security-model.md, "Trust Boundaries" and the threat matrix row "Compromised host application"; README.md, "Quick Start". Intercis: intercis.io/validation-report, "What a deny actually does", which shows the response before and after; in the repository, grep -n _make_blocked_response apps/proxy/main.py.
What each side can and cannot see Only traffic that crosses the Anthropic and OpenAI API wire is judged. A tool the provider runs on its own servers has already run by the time the response reaches us: hosted MCP calls, web search, file search, code interpreter and image generation are listed in _HOSTED_ITEM_TYPES in apps/proxy/openai_routes.py, and each one is observed, not governed: it writes one observe row and is never judged or blocked. A provider or a route we do not speak yet is not governed, and adding one is engineering work on our side. Whatever the application routes through it, and nothing else. policy-engine/docs/security-model.md: "An uninstrumented call path is outside the ACS guarantee", and its threat table lists "Policy bypass through uninstrumented paths" with the status "Host responsibility". It sees MCP tool calls the sidecar is asked about (docs/FAQ.md section 2) and eight lifecycle points including input, model call, tool call and output (policy-engine/README.md, "Intervention points"). docs/LIMITATIONS.md sections 1, 7 and 8 state it does not govern reasoning, knowledge retrieved by RAG, or the credentials an agent holds. Toolkit: policy-engine/docs/security-model.md, "Trust Boundaries" and "Out Of Scope Threats And Non Goals"; docs/LIMITATIONS.md sections 1, 7, 8. Intercis: intercis.io/limitations, second and fifth costs; intercis.io/validation-report, "Hosted MCP tool calls are observed, not governed".
Streaming Buffered, and the cost is ours to carry. To judge a tool call we have to see all of it, so a streamed response is collected in full, reassembled and judged before any of it reaches the agent. That adds latency equal to the length of the stream before the first token arrives, and on an interactive coding agent a person waits through it. We publish no latency number. Not covered at the token level. docs/LIMITATIONS.md section 11 states policies are evaluated per action at invocation time. policy-engine/docs/security-model.md states "ACS does not provide token or chunk level streaming enforcement. Hosts evaluate complete model and output snapshots", and requires that "The host must aggregate streams before calling post_model_call or output". Toolkit: docs/LIMITATIONS.md section 11; policy-engine/docs/security-model.md, "Out Of Scope Threats And Non Goals" and "Required Integration Invariants". Intercis: intercis.io/limitations, third cost; intercis.io/validation-report, "There is no latency figure". Both sides need the whole response before they can judge it.
Languages and frameworks Language-independent and framework-independent, because we are not in the code. Any agent in any language on any framework is governed if its provider calls reach us, and the agent's code does not change. The bound is the other way round: we speak three provider routes, so a provider we do not speak is not governed however the agent is written. Broader than ours, and this is a row where the toolkit is ahead. Five language packages: Python, TypeScript, .NET, Rust and Go (README.md, "Install"; docs/FAQ.md section 4). README.md, "Framework Support" lists fourteen integrations including Microsoft Agent Framework, Semantic Kernel, AutoGen, LangGraph, LangChain, CrewAI, the OpenAI Agents SDK, Google ADK, LlamaIndex, Haystack, Dify and Azure AI Foundry. docs/FAQ.md section 4 states Python has the full stack and the other four carry core governance. Toolkit: README.md, "Install" and "Framework Support"; docs/PACKAGE-FEATURE-MATRIX.md for per-language coverage. Intercis: intercis.io/limitations, fifth cost, which names the three routes.
Policy language and who writes the rules We ship the rules and you narrow them. The deterministic deny list is ours, maintained by us, and it is the floor under every tenant; on top of it a tenant sets modes and exclusions and an LLM classifier runs only when the deny list misses. Nobody writes Rego to use Intercis, and nobody can read our rule set either: Intercis is closed source, permanently, and the deny-list patterns are not published. You write them, in one of several languages. README.md, "Quick Start" shows a YAML policy with condition expressions and actions deny and require_approval. policy-engine/README.md, "Policies" lists the supported types as rego, cedar, test and custom, so rules can be Open Policy Agent Rego or Cedar. A manifest binds one policy per intervention point. Toolkit: README.md, "Quick Start"; policy-engine/README.md, "Policies" and "Manifest schema overview". Intercis: intercis.io/validation-report, "What the pattern layer catches"; the closed-source position is the decision record dated 2026-07-27 in our repository.
Audit record and tamper evidence One row per governed event in a database the agent cannot reach. A row carries the tenant, the agent, the tool name, a short excerpt of the command or path, the verdict, the policy, whether an injection was seen, the wire route, a command fingerprint, the classifier status and reason, and the structured tool input. A trigger computes a SHA-256 over the previous row's hash and every length-prefixed column of the event except that tool input, one chain per tenant; rows recorded before 2026-09-20 are hashed over ten named fields. No client role holds UPDATE or DELETE. We call it tamper-evident, not tamper-proof: anyone holding database-owner rights can rewrite rows and recompute the hashes. An append-only log with cryptographic chaining, described in a formal spec. SECURITY.md, threat table: "Audit tampering ... Append-only audit log with cryptographic chaining". README.md, "Specifications" lists "Audit and Compliance" with Merkle audit and 157 conformance tests. docs/LIMITATIONS.md section 2 is explicit that the log records what the agent attempted, not whether the action succeeded. Their guidance is to write the log outside the agent: SECURITY.md, "Operator guidance": "Enable audit logging to an external, append-only store. Agents should not have write access to their own audit logs." Toolkit: SECURITY.md, threat table and "Operator guidance"; docs/specs/AUDIT-COMPLIANCE-1.0.md; docs/LIMITATIONS.md section 2. Intercis: intercis.io/validation-report, "The record the decision leaves behind", and run the published verifier, verify_event_chain.py, on the published sample, sample-chain.json, yourself.
Identity Bound to the API key, and only when you bind it. An Intercis key can be bound to exactly one agent; then the identity is a property of the credential, a header naming a different agent is refused with an audit row, and an inactive agent fails closed. An unbound key is the weaker case and is the default for every key issued before the change: the agent id is self-asserted in a header and checked only for existence inside the tenant, so one holder of a tenant key can present another registered agent's id. We have no cryptographic agent identity. Cryptographic, and this is a row where the toolkit is ahead. Agents carry a decentralised identifier verified by an Ed25519 signature, with trust scores and delegation chains (README.md, "How It Works" and "Packages"; docs/specs/AGENTMESH-IDENTITY-TRUST-1.0.md, 135 conformance tests). Two honest wrinkles are in their own docs: docs/LIMITATIONS.md section 12 records two different identifier prefixes across the SDKs, and SECURITY.md carries advisory GHSA-5j58-vjjg-pcgm, in which the HTTP trust middleware accepted caller-supplied identity without binding it to the whole request, fixed in 5.0.1. Toolkit: README.md, "Packages"; docs/LIMITATIONS.md section 12; SECURITY.md, "Security Advisories". Intercis: the decision record dated 2026-09-02 on agent identity binding to the API key, in our repository, which states the residual in its own words.
Sandboxing and process isolation None. Intercis does not sandbox, isolate or terminate a process. We judge provider calls and write the record; everything the agent does that is not a provider call is outside us. If what you need is an execution sandbox, this product is not it. Present, and this is a row where the toolkit is ahead: we have nothing here. README.md, "Packages" lists Agent Runtime as "Execution sandboxing with four privilege rings" and Agent Hypervisor for execution audit and command denylist enforcement, with a formal spec and 80 conformance tests. They bound the claim themselves: README.md, "Security" says enforcement is at the application middleware layer, not the OS kernel, and recommends "Run each agent in a separate container for OS-level isolation"; docs/LIMITATIONS.md section 6 lists "OS kernel / hardware isolation" under what AGT is not. Toolkit: README.md, "Packages" and "Security"; docs/specs/AGENT-HYPERVISOR-EXECUTION-CONTROL-1.0.md; docs/LIMITATIONS.md section 6. Intercis: intercis.io/limitations lists what we cover; no sandbox appears on it or on intercis.io/validation-report.
Measured numbers published How often our own rules flag work that was fine. On 4,764 governed tool calls from our own Dogfood tenant, all labelled benign, today's rules flag 737. That is 15.47%, Wilson 95% 14.47% to 16.52%. The window is 25 August to 4 September 2026 with 31 August excluded, the day a four-hour classifier outage voided it under our own runbook; the full window including that day reads 13.46% and is printed too. Separately, the deterministic deny list catches 40 of 47 payloads in our own in-repo threat corpus, 85.1% recall, and that corpus is written by the defender, so it measures regression stability and not adversarial robustness. We publish no latency number at all. Test counts, a policy-evaluation latency figure, and a self-assessed standards mapping. README.md states "992 conformance tests" and, under "Documentation", "10 formal specs, 992 conformance tests"; its own Specifications table lists eleven rows, so treat the spec count as approximate and the test count as theirs. docs/LIMITATIONS.md section 3 publishes policy evaluation at under 0.1 ms and is careful about it: that number "measures the policy engine only", and the same section gives 5 to 50 ms per governed inter-agent interaction for a multi-agent mesh. Their OWASP claim is theirs and we do not endorse or dispute it: docs/compliance/owasp-agentic-top10-architecture.md reads "Official ASI coverage: 7/10 Full, 3/10 Partial, 0 Gaps", and the same file opens with their own disclaimer that it "is an internal self-assessment mapping, NOT a validated certification or third-party audit". They also publish a re-runnable false-positive figure for one component: docs/benchmarks/prompt-injection-evaluation.md reports the Rust prompt-injection detector on a 280-row synthetic smoke corpus, 16 of 170 benign rows flagged (0.0941) and 7 of 110 attack rows caught (recall 0.0636), reproduced with bash benchmarks/prompt-injection/run-smoke.sh. Their own caveat sits beside it: the numbers "should not be presented as production AGT detector performance". A rate of that kind measured on real agent traffic was not found in a search of every markdown file in the repo at this commit. Toolkit: README.md, "Specifications"; docs/LIMITATIONS.md section 3; docs/compliance/owasp-agentic-top10-architecture.md, "Coverage Summary" and the disclaimer above it. Intercis: intercis.io/validation-report and intercis.io/validation-report/benign-corpus, and re-run python scripts/detection_bench.py yourself. The two figures in this row are not comparable and this page does not set them side by side as if they were: theirs is one detector on a 280-row synthetic corpus, with their own caveat beside it, and ours is the whole rule set on 4,764 real calls from one tenant, ours.
Licence, cost and how you buy Paid, closed source and hosted. $200 a month for the first agent and $190 for each additional agent, on the pilot page. The entry point is a 90-day pilot on the Team tier with no commitment required, and the pilot is paid at that rate. The only tiers are Team and Enterprise, and there is no self-serve signup. You cannot read our source, and we do not sell or support a self-hosted build; how one would be licensed is not decided. Putting us in the path also adds a trust boundary your prompts and tool inputs cross in plaintext, and the classifier call goes out on an Intercis credential carrying the tool name and the full tool input. Free and open source, and this is a row where the toolkit is ahead. MIT licence (LICENSE, and README.md, "License"), installed with pip install, npm install, dotnet add package, cargo add or go get (README.md, "Install"). docs/LIMITATIONS.md section 5 states the core packages carry zero Azure or Microsoft dependencies and run offline, on AWS, GCP, on-premises or air-gapped. You can read every rule and fork it. Toolkit: LICENSE; README.md, "Install" and "License"; docs/LIMITATIONS.md section 5. Intercis: intercis.io/pilot for the price, intercis.io/limitations for the fourth cost.
Maturity and who maintains it One person, pre-revenue, and we will not dress that up. Intercis is a solo-founder company in Raleigh, North Carolina. It has no customer, no logo, no revenue figure and no compliance certification: not SOC 2 certified, no audit underway, no auditor engaged, and no SOC 2 or ISO 27001 evidence package generated. Per-provider route maintenance is ours for as long as the product exists. A Microsoft-led open-source project in public preview, and on team size this row is theirs. README.md carries a "Public Preview" notice reading "production-quality public preview releases. May have breaking changes before GA", and CHANGELOG.md repeats it. MAINTAINERS.md, last updated May 2026, lists a project lead and five core maintainers: three of those six are at Microsoft and three are at other organisations. The contributor ladder is written down in GOVERNANCE.md. The CHANGELOG.md "Unreleased" section carries entries marked BREAKING. Security reports go to secure@microsoft.com under a 90-day coordinated disclosure policy (SECURITY.md). Toolkit: README.md, the Public Preview notice; MAINTAINERS.md; GOVERNANCE.md; SECURITY.md; CHANGELOG.md. Intercis: intercis.io/validation-report, "Intercis is not SOC 2 certified", and intercis.io/limitations, fifth cost.

What was read, and what a "not found" cell means. The Microsoft column comes from files opened whole in a local clone at commit 8f1d0e1 on 18 September 2026: README.md, SECURITY.md, MAINTAINERS.md, CHANGELOG.md (head), docs/LIMITATIONS.md, docs/FAQ.md (sections 1 to 4), docs/compliance/owasp-agentic-top10-architecture.md (head), policy-engine/README.md and policy-engine/docs/security-model.md. Six further files appear above as signposts for the reader and were not opened. So a cell saying something is not in the repository means not in the files named here, and the one search of every markdown file in the clone is the one named in the measured-numbers row.

When each is the better choice

When the toolkit is the better choice

Most of the time, on this evidence. It costs nothing, you can read every rule, and it speaks five languages and a dozen frameworks. If you write all the agent code yourself and can hold the line in code review, an in-process library is the cheaper guard and the faster one. If you need an execution sandbox, privilege rings or cryptographic agent identity, we do not have them and the toolkit does. If your agents are Microsoft Agent Framework or Semantic Kernel, it is one middleware registration.

When a proxy is

When the agent process itself is part of the threat. A library the application calls can be skipped by the application: their own security model puts a compromised host out of scope and says a decision cannot force malicious host code to obey it. A proxy outside the process removes that skip, and the audit log sits somewhere the agent cannot write to. It also helps when several teams use different frameworks and you would rather change one setting than every service. The price is an infrastructure change, buffered streaming, and an egress rule to stop a compromised process routing around us.

Both at once

They stack, and saying so is more honest than picking. The library catches what it catches before the request leaves; the proxy judges what reaches the wire. Switch one off and the other still runs. The cost is two sets of rules to keep straight. The same argument, in the same words, is on proxy against SDK enforcement.