신규: AIBOM — 모든 에이전트·도구·커넥터의 실시간 BOM. 자세히 보기
MITRITY
Docs / Gateway·Sidecar·메시 / Governance Coverage

Governance Coverage

This page states what MITRITY governs and what it does not.

It names each execution path, says whether it crosses a MITRITY decision point today, and shows how to close the ones that do not. The same rule applies here as on the mesh egress allowlist and the SaaS connectors: MITRITY reports an action as enforced only when it decided it, and as seen only when it reached a MITRITY component.

The short version

MITRITY governs the actions that cross a MITRITY decision point. Every decision point that exists today is listed below.

Anything an agent does without crossing one of them is not evaluated, not blocked, and not in your audit log. In practice that means two things, and they are the two things most people are surprised by:

  1. Your agent framework's own built-in execution tools — Claude Code's Bash, LangChain's ShellTool, CrewAI's code interpreter — never produce an MCP tools/call. Pointing an agent at Mitrity Gateway governs the tools the gateway serves; it does not govern the tools the framework already had.
  2. Code the agent runs itself — a subprocess.run(...) inside a custom tool, or a command a human types in the same shell — never reaches a MITRITY binary at all.

Both can be closed today by configuration. Make the gateway the only execution path is the checklist; the roadmap lists the product changes that close them further.

Governed today

Decision pointWhat is evaluatedWhere
Mitrity Gateway — MCP tools/callEvery tool call to a gateway-aggregated upstream, before dispatchIntegration Modes
Mitrity MCP Sidecar — MCP tools/callEvery tool call to the one wrapped upstream server, before forwardingIntegration Modes
Native HTTP tools on the gatewayHTTP APIs declared as tools in native_tools[]; the gateway issues the request, so the same pipeline appliesConfiguration Reference
Mitrity Mesh Authorizer (mitrity-extauthz)East-west and agent-to-agent (A2A) requests in Istio, plus mesh egress by destination/SNIMesh Enforcement
Mitrity LLM Gateway (mitrity-llm-gateway)Prompts and model responses on LLM egress: model allowlists, token caps, budgets, rate limits, wire redactionLLM Gateway
Platform connectors (SaaS-embedded agents)Discover, Observe, Posture — read-only, after the factSaaS-Embedded Agents

On the four runtime surfaces the full pipeline runs before the action executes: policy and rule constraints, DLP, prompt-injection scanning, threat-intel matching, delegation-chain state, mission-scoped credential injection, and human-approval holds. Platform connectors are the exception: they observe and assess, they do not block.

What "MCP" covers, precisely

Only tools/call.

  • Mitrity MCP Sidecar intercepts tools/call and forwards every other JSON-RPC method to the upstream untouched — including resources/read, prompts/get and sampling/*.
  • Mitrity Gateway implements initialize, tools/list, tools/call and ping. Any other method returns a JSON-RPC Method not found error rather than being governed.

If an upstream MCP server exposes sensitive data as a resource rather than a tool, the sidecar will pass that read through and the gateway will refuse it. Neither is governance.

Not governed today

Each entry describes the path, how to close it with configuration you control, and the release that changes it. See the roadmap for the full table.

Framework built-in execution tools

Every major agent framework ships tools that execute code or touch the filesystem without going through MCP: shells, code interpreters, file writers, web fetchers. They run inside the agent process and never produce a tools/call, so no MITRITY binary sees them.

Today this is closed by disabling those tools — the per-framework settings are in the table below.

Changes with: a PreToolUse hook plus rendered managed settings for Claude Code and the Claude Agent SDK, then language adapters for LangChain, the OpenAI Agents SDK and CrewAI.

Direct OS calls from the agent's own code

A custom tool that calls subprocess (Python), os/exec (Go), or any other process-spawning API executes directly. So does a command a person types on the same host. Neither crosses a decision point, so neither is evaluated or recorded.

Containment today is structural, not policy-driven: run the agent in a distroless container with no shell and no package manager, as a non-root user, with credentials held by the gateway rather than the agent.

Changes with: a first-party governed shell in the gateway (executes the exact bytes it judged, inside a kernel sandbox) for the in-agent case; the Linux host observer for attribution of the rest — detection, not prevention.

Wrapped and scripted commands

Two evasions used to sit outside governance, and both are now caught on the governed paths — with caveats stated below.

Wrappers. The command line is parsed with a real shell grammar: bash -c "rm -rf /", sudo, env, timeout, xargs, find -exec, pipelines and inline interpreters are unwrapped, and rules match the resolved commands (resolved_commands, exec_features, on_unparseable) rather than the first word. What cannot be resolved — a decoded payload piped into a shell, a dynamic command word — is a named feature that fails closed.

Scripts. A script the command references is read under the policy's script_inspection_roots and, for shell scripts, its inner commands are merged into the evaluated tree: a deny rm rule fires on bash deploy.sh when the script contains rm -rf /. Writing the commands in one call and running the file in another is linked by the edge taint store — script_authoring on the write, write_then_run on the execution, modified_outside_governance when the file changed in between — and taint_action / autorun_write_action decide what happens. See Scripts, write-then-run and autorun paths.

What this does not cover, stated plainly:

  • Non-shell script bodies. A Python, Node, Perl or Ruby script is hashed, DLP-scanned and injection-scanned, not semantically analyzed. The sandbox bounds its effect; the parser does not understand it.
  • Code handed to a tool the edge does not treat as executing. A code argument is content: fingerprinted, DLP- and injection-scanned and, on a write, judged as the script being authored — but parsed as a command only on a tool whose name says it executes it (execute_code, python_repl). On every other tool a code body no rule judged — a path-less call, or a written body that is not a shell program — carries code_body_unjudged, naming the tool and the key, so the gap is visible per tool in the audit log rather than silent; a shell body written through such a tool is judged as the script being authored and needs no stamp. Two policy settings govern the gap: code_execution_tools names further tools (by tool_pattern) whose code is judged as the command they run, and unjudged_code_action decides what happens to an action that still carries the finding — alert by default, hold or deny (Writing Policies). A per-tool catalog signal will later replace the name test.
  • TOCTOU until the governed shell. The script's hash is recorded at decision time; the framework or upstream tool runs the file afterwards, and it can change in between. That change is detected on the next decision (modified_outside_governance), not prevented. Only the first-party governed shell, which executes the exact bytes it judged inside a kernel sandbox, closes the window — and it says exactly what it does and does not bound.
  • Scripts outside the roots are not read at all: the execution is script_unresolvable and denied by default — a configuration gap you widen deliberately, never a silent pass.
  • Host activity outside governed paths — see below: on macOS and Windows a script the agent runs without crossing a decision point is invisible.

Changes with: semantic command policy in edge release v0.20; script inspection and write-then-run taint in v0.21; the first-party governed shell (judged bytes executed inside a kernel sandbox, credentials outside argv, output through DLP) in edge release v0.21.

MCP resources, prompts and sampling

As above: forwarded by the sidecar, refused by the gateway, governed by neither.

Changes with: not currently planned.

DNS and raw sockets

Governed egress is HTTP(S)-shaped. The mesh egress allowlist is network-layer and destination/SNI-based; the LLM Gateway terminates TLS for LLM traffic only. An agent that resolves names or opens raw sockets directly is outside both.

Lock this down with network controls you already own — a NAT egress allowlist, or Istio REGISTRY_ONLY plus the mesh egress allowlist.

Changes with: not currently planned.

Vendor-cloud hosted tools

The OpenAI Agents SDK's CodeInterpreterTool, HostedMCPTool and WebSearchTool execute in OpenAI's cloud, not on your host. No local edge can see or stop them — this is a structural limit, not a missing feature. If a workload must be governed, do not give it hosted tools.

Changes with: nothing can change this locally. The OpenAI adapter will flag hosted tools as ungoverned in the agent's coverage posture so the gap is visible rather than assumed away.

Host activity on macOS, Windows and serverless

Runtime observation of what an agent's process tree actually executed is a Linux capability: it reads kernel process events. There is no equivalent on macOS, on Windows, or in serverless runtimes such as Cloud Run and Lambda, where no kernel-level process view is available to a workload.

Changes with: mitrity-host-observer, Linux only. macOS, Windows and serverless host activity are explicitly out of scope for the current quarter.

Agent frameworks: built-in execution tools

The settings in the third column are available to you today and need nothing from MITRITY. The fourth column is the roadmap.

FrameworkBuilt-in execution toolsHow to disable or restrict them todayWhat MITRITY will add
Claude Code / Claude Agent SDKBash, Write, Edit, MultiEdit, NotebookEdit, WebFetch, WebSearch — all bypass MCPpermissions.deny with Bash(...) rules; the native Bash sandbox: sandbox.enabled: true, allowUnsandboxedCommands: false, failIfUnavailable: true, sandbox.network.allowedDomains; restrict MCP to the gateway with allowedMcpServers; make hooks non-removable with allowManagedHooksOnlyA PreToolUse hook that decides every built-in tool call before it runs (deny via exit code 2 / permissionDecision: "deny"), and a renderer that generates the managed settings above from the agent's mission profile
LangChain / LangGraphShellTool, PythonREPLTool, FileManagementToolkitDo not put them in the tools list you pass to the agent — expose only the gateway's MCP tools. There is no runtime switch; the tool list is the controlA Python adapter that wraps a LangChain tool so its invocation is evaluated by the edge before it runs
OpenAI Agents SDKLocalShellTool (local); CodeInterpreterTool, HostedMCPTool, WebSearchTool (hosted, run in OpenAI's cloud)Omit LocalShellTool. The hosted tools cannot be governed by any local edge — omit them from agents that must be governedA function-tool wrapper for local tools; hosted tools flagged as ungoverned in the agent's coverage posture
CrewAICodeInterpreterTool; allow_code_execution=True on an AgentLeave allow_code_execution at its default (False) and do not add CodeInterpreterToolA CrewAI adapter in the second wave of adapters
smolagentsPythonInterpreterTool; a CodeAgent executes the Python it generates, by designUse ToolCallingAgent instead of CodeAgent, and do not add PythonInterpreterTool. If you need CodeAgent, treat the agent as ungoverned for executionNo adapter on the current roadmap. On Linux, the host observer will attribute what the agent actually executed, after the fact
Custom code (any language)Whatever the agent process can call: subprocess (Python), os/exec (Go), and equivalentsNothing in a framework to switch off. Route execution through a governed tool, and contain the process: distroless image, non-root, no shell, no package manager, no credentials in the agentThe governed shell (the shell__execute tool, action type shell:execute) as a first-party gateway tool, so there is a governed execution path to route to; Go and Python adapters

Make the gateway the only execution path

Governance coverage is a property of your configuration, not of the binary. This is the checklist that produces it:

  1. Expose exactly one MCP server to the agent — the gateway. Remove every other mcpServers entry. On Claude Code, enforce it with allowedMcpServers.
  2. Turn off the framework's built-in execution tools, using the settings in the table above. This is the step that is most often skipped, and it is the one that matters most.
  3. Give the agent process no credentials. Upstream secrets belong to the gateway; the agent authenticates to the gateway. An agent that holds a token can use it without asking.
  4. Run the agent in a container with no shell and no package manager, as a non-root user, from a distroless base. If there is no sh, a great deal of improvised execution simply fails.
  5. Lock egress. A NAT or firewall allowlist, or Istio REGISTRY_ONLY plus the mesh egress allowlist, so the agent cannot reach anything the gateway did not route.
  6. Spawn the edge from the agent's own MCP client over stdio. Both binaries are stdio programs; a detached "gateway service" the agent dials over the network is not a supported topology. See the deployment guide.
  7. Verify against the audit log, not against intent. Run the agent through a realistic task and compare what it did with what the audit log contains. Anything it did that is not in the log was, by definition, ungoverned.

The execution-coverage badge

Every agent in the dashboard carries an execution-coverage badge, and the agent page has an Execution coverage card behind it. The badge answers one question: is this agent actually governed? It answers from two independent sources, never from one.

  • Attested — what the runtime says about itself. On Claude Code and the Claude Agent SDK, mitrity-hook session-start reports which built-in tools the hook intercepts, which execution-capable tools it does not, which other MCP servers are configured, the permission mode and the sandbox settings. This is self-reported by the process the model runs inside. It is evidence, not proof: a hook that was quietly removed still leaves a settings file that says it is there.
  • Observed — what the edge actually saw. On every heartbeat the gateway reports how many admission decisions and MCP calls it handled in the last minute, and the control plane keeps the last time each was ever seen. The runtime does not control these counters.

The badge is the intersection. A self-asserted attestation alone never turns it green.

The five states

BadgeMeaningWhat turns it into governed
GovernedThe runtime attests full coverage, nothing is flagged, and the edge has seen the hook in the loop (at least one admission decision).
PartialAttested, but either not yet corroborated by traffic, or not fully isolated: a medium or low finding is open. The most common reason on a fresh install is simply that no built-in tool call has passed through the hook yet.The first admission decision, or closing the open finding.
DegradedPart of the execution surface is outside governance: a high finding is open — an execution tool the hook does not cover, a second MCP server, or a sandbox that allows commands to escape it. A notification (agent.execution_coverage_degraded) fires when an agent enters this state.Closing every high finding.
UnattestedThe runtime's framework has built-in execution tools (Claude Code's Bash, LangChain's ShellTool, …) and it has never attested. The hook or adapter is not installed, or never reached the edge.Installing the hook and starting a new session.
UnknownNothing to assess against: no attestation, and either no framework is named or the named framework has no catalogued built-in execution tools. Not a pass and not a failure — MCP calls through the gateway are governed either way; execution from the agent's own code is not observable on this runtime.An adapter for the framework, when one exists.

Why attestation alone never means governed

The attestation comes from inside the agent's trust boundary — the same process the model, and anything that has persuaded the model, runs in. It can be accurate but stale, accurate but misconfigured, or simply gone while its settings file remains. So the control plane treats it as one axis and demands corroboration from the other:

  • An attestation that hooks tools but has never produced an admission decision reads partial (no_corroborating_traffic), not governed.
  • An attestation that hooks tools while ten consecutive heartbeats carry MCP calls and zero admission decisions reads partial (hook_silent): the settings file names a hook the edge is not hearing from.
  • An attestation that stops being carried by heartbeats for 15 minutes reads partial (attestation_stale) — freshness is measured on the last heartbeat that carried it, because the hook attests once per session and the edge re-ships it on every beat.
  • An edge that restarts without the runtime re-attesting reads unattested, not the last thing it said.

The Linux host observer is the third axis: an exec whose process ancestry never passed through a MITRITY binary counts against the badge regardless of what the runtime attests (observer_ungoverned_execution, high), and a host whose observer falls silent reads partial (observer_offline, medium). The card's observed axis shows whether the observer is present for the agent, its last event and the ungoverned count of the last 24 hours; presence on its own never improves the badge.

Findings and how to close them

The card lists every open finding with its severity, when it was first seen, and what to change. The vocabulary:

FindingSeverityWhat it meansRemediation
attestation_missinghighThe framework has built-in execution tools and the runtime has never attested.Install mitrity-hook and add its SessionStart and PreToolUse entries to the runtime settings — as managed settings on managed machines — then start a new session.
attestation_stalemediumNo heartbeat has carried the attestation for more than 15 minutes.Check that the edge is running and heartbeating. If the runtime restarted, a new session re-attests on its own.
unhooked_exec_toolshighExecution-capable built-in tools the hook does not intercept (tools the runtime disables outright are not counted).Extend the PreToolUse matcher to cover the listed tools, or disable them with permissions.deny. On managed machines set allowManagedHooksOnly so the matcher cannot be narrowed locally.
other_mcp_servershighMCP servers configured alongside the MITRITY gateway — each is a second, ungoverned tool path.Remove the other mcpServers entries, or pin allowedMcpServers to the gateway alone (allowManagedMcpServersOnly on managed machines).
sandbox_disabledmediumThe framework has an OS sandbox and it is disabled or not configured.Set sandbox.enabled: true.
unsandboxed_commands_allowedhighThe sandbox is on but commands may run outside it — including when allowUnsandboxedCommands is simply absent, which is the framework default.Set sandbox.allowUnsandboxedCommands: false.
sandbox_not_requiredlowThe runtime runs unsandboxed rather than refusing when the sandbox cannot start.Set sandbox.failIfUnavailable: true.
permission_mode_bypassmediumThe session runs in bypassPermissions or dontAsk, so the framework's own prompts are skipped and the hook is the only gate.Run the session in default or acceptEdits mode.
hook_silentmediumHooked tools are attested, but ten consecutive heartbeats carried MCP calls and no admission decisions.Run mitrity-hook doctor on the host: confirm the binary is on PATH, the admission socket is reachable and the PreToolUse command resolves.
no_corroborating_trafficmediumAttested, but no admission decision has ever been observed for this agent.Nothing is wrong yet — the badge turns governed after the first built-in tool call passes through the hook. If the agent has been active for a while, treat it as hook_silent.
config_driftinfoThe runtime's configuration hash changed within the last 24 hours. Shown as a note; it never moves the badge and clears on its own.Review the settings change. Expected after a deliberate change; worth a look otherwise.

A disabled hook engine (disableAllHooks) does not get its own finding: the hook reports it as every execution tool being unhooked, which is exactly what it is.

Installing the hook

mitrity-hook ships with the edge release that carries the admission API, and its integration guide (Integrations → Claude Code) lands with it. Until that page exists, the attestation_missing remediation is the install recipe in full: put the mitrity-hook binary on the runtime host's PATH, add mitrity-hook session-start under hooks.SessionStart and mitrity-hook pre-tool-use under hooks.PreToolUse (matching the execution-capable tools) in the Claude Code settings — as managed settings with allowManagedHooksOnly on managed machines — and start a new session. The badge moves from unattested to partial on the first heartbeat that carries the attestation, and to governed on the first built-in tool call the hook decides.

Filtering the agents list

The agents list has a coverage filter (?execution_coverage=<state>) that uses the same rules the badges do, so a filtered list and the badges it shows always agree. Filter for degraded and unattested first: those are the agents whose execution is, in part or in whole, invisible to MITRITY today.

Execution states on events

Two closed vocabularies say, on every event, how much isolation and attribution actually applied. Neither is a promise: each is stamped by the component that did the work, and a missing value means "not ours to vouch for", never "fine".

sandbox_mode — the governed shell

Stamped on every execution-shaped event the governed shell produces (shell:execute, and a hooked Bash routed into it). Events from executions the edge did not run — a Bash the framework executed itself, an upstream MCP tool — carry no sandbox_mode at all.

ValueMeaning
bubblewrapLinux: bwrap with user, pid, net, ipc and uts namespaces, a read-only root and the seccomp stage installed. Full strength
bubblewrap_no_seccompLinux: bwrap as above without the seccomp stage. Only reachable with exec.sandbox.seccomp: preferred. Degraded; notifies
seatbeltmacOS: sandbox-exec with the generated profile. Full strength for the platform
noneThe command ran with no kernel isolation, because the policy allowed it (sandbox_required: false). Degraded; notifies
unavailable_deniedNo sandbox backend was available and sandbox_required: true denied the call. Nothing ran. Notifies

A degraded mode raises execution.sandbox_degraded with the reason (userns_disabled, bwrap_missing, seccomp_unavailable, …). In a container the usual reason is the runtime's default seccomp profile blocking unprivileged user namespaces; the chart READMEs list the node prerequisites, and none of them is privileged.

classification — the host observer

Stamped by mitrity-host-observer (Linux only) on every process execution it reports, from process ancestry alone — the runtime's own attestation is not consulted.

ValueMeaning
governedThe execution passed through a MITRITY entrance: an ancestor is the agent's gateway or sidecar (or an attested upstream), the process is a MITRITY binary itself, or the control plane joined it to an admission decision
ungovernedThe execution is inside an agent's process tree and did not pass through an entrance. This is the finding that counts against the coverage badge
unattributedOutside every known agent tree, or the ancestry chain could not be completed. Recorded only when a runtime rule matches. An incomplete chain is never reported as ungoverned — the unseen link might have been the entrance

Both vocabularies arrive with the edge releases that ship the governed shell and the observer — see the roadmap.

Windows

Windows coverage is narrower than Linux and macOS, and worth stating plainly:

Windows today
Mitrity GatewayNo Windows binary. The gateway ships as a Linux amd64/arm64 binary and container image
Mitrity MCP SidecarSupported — windows/amd64 binary
Claude Code Bash sandboxNo native Windows implementation (Seatbelt on macOS, bubblewrap on Linux and WSL2). Under WSL2 the Linux sandbox applies
Host observationNot available. The observer reads Linux kernel process events
Planned hookWill build for Windows, but command analysis assumes POSIX shell grammar

For a Windows agent host today, the practical combination is the sidecar plus disabled built-in execution tools plus network egress controls — or run the agent under WSL2 and treat it as a Linux host.

Roadmap

Roadmap as of September 2026. This table is the only forward-looking part of this page; everything else describes behavior that ships today. Targets are plans, not commitments, and customer demand drives priority.

GapWhat closes itTarget
Claude Code / Agent SDK built-in tools ungovernedmitrity-hook (PreToolUse) + managed-settings rendering from the mission profileShipped in edge release v0.20
Wrapper and interpreter evasion of commandsSemantic command policy: shell grammar, unwrapping, resolved_commands, exec_features, on_unparseableEdge release v0.20
Scripts and write-then-runScript inspection under policy roots (inner commands merged into the tree), taint tracking, write-time findings, taint_action / autorun_write_actionEdge release v0.21
TOCTOU on judged bytesFirst-party governed shell: executes the exact bytes it judged, inside a kernel sandbox, with output-phase DLP; routes Claude Code's Bash through it with builtin_exec_routingEdge release v0.21
Direct host execution on Linuxmitrity-host-observer — process-ancestry attribution, flags ungoverned execution. Detection, not preventionEdge release v0.21, Linux only
LangChain, OpenAI Agents SDK, CrewAI built-insLanguage adapters (Python, TypeScript, Go)Adapter packages 0.1; the OpenAI Agents SDK and CrewAI adapters follow in 0.2
Whether an agent is actually fully governedExecution-coverage posture: runtime attestation corroborated by traffic, shown as a per-agent badge — see The execution-coverage badge. The observer axis follows with the observerShipped (badge and findings); the observer axis arrives with the host observer in edge release v0.21
macOS / Windows / serverless host activityNot currently planned
Kill-on-match, synchronous kernel verdictsNot currently planned
DNS and raw-socket egress; body inspection of arbitrary egressNot currently planned
Vendor-cloud hosted toolsStructurally out of reach for a local edge
MCP resources, prompts, samplingNot currently planned