Permit.io is an authorization control plane and policy engine you call from your code, plus a proxy you point at individual MCP servers. Tenure is a protocol-level gateway your requests pass through.
Permit.io ships two things that both get called "AI security." The core Policy Engine is an authorization API: you call permit.check() at the points in your code where you've decided a decision matters, and it's evaluated against RBAC, ABAC, or ReBAC policy. Enforcement exists where a developer remembered to instrument it, in whatever framework they're already using.
The MCP Gateway is a separate product, where you route an upstream MCP server's traffic through a Permit-issued URL, and every tool call to that server is authenticated, checked against an auto-generated OPA policy, and logged before it reaches the server. That part of Permit's story is architecturally close to Tenure's: out-of-process, protocol-level, no code changes to adopt.
The difference is scope. The Gateway only sees traffic for MCP servers you've explicitly routed through it, one upstream URL at a time. It doesn't see tool calls that reach a service directly, and it doesn't see non-MCP function calling at all. For teams whose agents call tools directly through native function-calling APIs, with no MCP server anywhere in the path, the Gateway has nothing to attach to. That's not a partial gap; MCP isn't part of that architecture at all. Tenure sits on the model request itself, so it checks every returned action regardless of whether the target tool speaks MCP, some other protocol, or nothing standardized at all.
Permit's own MCP Gateway page acknowledges the gap: its enterprise tier adds IGA/PAM connectors specifically because, in their words, "agents won't always go through the gateway." Tenure doesn't have an equivalent "which servers did we forget to route" list, because there's no per-server routing decision to make.
Unrouted MCP servers. A team connects a new MCP server and starts using it before anyone updates the gateway routing. Until that URL is proxied through Permit, every call to it is ungoverned. This is the exact scenario Permit built shadow-MCP detection to catch after the fact, not to prevent at the time.
No MCP layer at all. Function calling that doesn't go through an MCP server, direct API calls the model triggers, raw tool use over the OpenAI or Anthropic protocol without an MCP layer in between, sits entirely outside what the Gateway inspects. This isn't limited to teams migrating toward MCP. Plenty of production agents are built on native, direct function-calling and never touch MCP by design, whether for latency, simplicity, or because they predate MCP's adoption. For those teams the Gateway isn't a tool with a coverage gap, it's a tool that isn't in play.
Uninstrumented callsites. Where Permit's core Policy Engine is used instead of the Gateway, the same per-callsite problem AGT has applies: a new tool added after integration, or a code path that calls the underlying function without going through permit.check(), is simply not evaluated.
None of this requires an attacker. A new integration, a tool added mid-sprint, or a team that reaches for direct function calling instead of MCP is enough to open a gap in either model. Tenure doesn't have a routing table or a wrapper list to keep current, because it isn't watching specific servers or specific callsites. It's watching the model request protocol itself, so whatever tool the model tries to call arrives already inside Tenure's view.
| Property | Tenure | Permit.io |
|---|---|---|
| Enforcement location | On the wire | SDK callsites + per-server MCP proxy |
| Requires per-callsite instrumentation | No | Yes, for the Policy Engine (permit.check()) |
| Requires per-server routing | No, single protocol endpoint | Yes, one upstream URL per MCP server |
| Covers non-MCP tool calls | Yes | No, MCP Gateway is MCP-only |
| Precondition evidence checks (field/type/value) | Yes | Not part of published spec |
| Human identity binding (OAuth 2.1 / IdP / SSO) | Yes, Token-scoped caller identity | Yes, native IdP binding |
| Human-in-the-loop consent UI | Hand off to your application logic | Yes, visual consent editor |
| Pre-built SaaS MCP server catalog | Not applicable, protocol-level | Yes, major SaaS servers pre-wired |
| Requires an SDK integration | No, any OpenAI/Anthropic client | Optional; required for the Policy Engine, not the Gateway |
| Self-hosted | Yes, always | Hosted by default; on-prem/VPC available on enterprise plans |
This comparison is based on Permit.io's public documentation and marketing pages as published at permit.io/ai-access-control and permit.io/mcp-gateway. Details are current as of publication; verify against the latest docs before citing specific figures.
No per-server proxy URL to configure. No callsite to remember. Every model request, whatever tool it tries to call, crosses the same checkpoint.