Chio/Docs
LOGIN · JOIN

Bypass resistance

See which paths can construct a kernel or dispatch a call, and how the build fails when a new one appears.

Research chio@5f63e6e

On this page

Every kernel construction and dispatch call that Chio's scanner finds in the source tree is named in a checked inventory, and an unlisted site fails the build.

The result covers the five scanned directories and excludes test-only code. Dispatch contracts and behavior tests cover what a static scan cannot see, and feature negotiation fixes which invocation semantics each session carries.

Site inventoryChoose a scan result.
sites the scan findsinventory entriesadapter-no-bypasss₁e₁ChioKernel::newconstructors₂e₂factory callconstructors₃e₃evaluate calldispatchs₄e₄delivery calldispatchpasss₅new call siteunclassifiede₅removed sitestalescaninventoryadapter-no-bypasss₁e₁s₂e₂s₃e₃s₄e₄passs₅unclassifiede₅stale

A new construction or dispatch site fails the build

A kernel constructor or dispatch call that the inventory does not already name fails as unclassified. Its author classifies the owner, entrypoint, and effect boundary before the build passes.

The completeness check over construction and dispatch sites, with four matched pairs drawn in place of the 31 constructor and 91 dispatch sites. Test-only code, the call-contract minimums, and the SDK parity lanes are left out.

A control holds only when every path to its effect passes the kernel

A check can be correct and still ineffective if the application has another way to perform the same action. A coding host may expose one file through a native tool, a protocol adapter, and a shell; an SDK wrapper may enforce a rule while a lower-level connector stays callable; a new adapter may keep the ordinary request fields and drop a security extension that changes admission. Constructors choose which authorities and stores exist, transports choose which commitments survive serialization, and dispatch sites choose which executor reaches the resource.

Routes from the agent to the resource, and whether every one crosses the kernelcut at Kwritable mounttnative toolinherited credentialrequestadmitteddispatchaKdRagentkerneladapterrepository/governed
mandatory(R)  ⟺  ∀ π∈Π(a,R): K∈π\text{mandatory}(R) \iff \forall\, \pi \in \Pi(a, R):\ \htmlClass{role-seal}{K} \in \pi
π0=(a,K,d,R)∋K\htmlClass{role-seal}{\pi_0 = (a, K, d, R) \ni K}
π1=(a,R)mount∌K\pi_1 = (a, R)_{\text{mount}} \not\ni K
π2=(a,t,R)∌K\pi_2 = (a, t, R) \not\ni K
π3=(a,R)cred∌K\pi_3 = (a, R)_{\text{cred}} \not\ni K
mandatory(R)=1\text{mandatory}(R) = \htmlClass{role-seal}{1}
every route to R crosses the kernelclick a dashed route to grant it
Routes from the agent to the resource, and whether every one crosses the kernelcut at Kwritable mounttnative toolinherited credentialaKdRagentkerneladapterrepository/governed
mandatory(R)  ⟺  ∀ π∈Π(a,R): K∈π\text{mandatory}(R) \iff \forall\, \pi \in \Pi(a, R):\ \htmlClass{role-seal}{K} \in \pi
π0=(a,K,d,R)∋K\htmlClass{role-seal}{\pi_0 = (a, K, d, R) \ni K}
π1=(a,R)mount∌K\pi_1 = (a, R)_{\text{mount}} \not\ni K
π2=(a,t,R)∌K\pi_2 = (a, t, R) \not\ni K
π3=(a,R)cred∌K\pi_3 = (a, R)_{\text{cred}} \not\ni K
mandatory(R)=1\text{mandatory}(R) = \htmlClass{role-seal}{1}
click a dashed route to grant it

Every route from the agent to the repository crosses the kernel, so admission is mandatory.

In Rust · lib.rs:25913 lines
/// Invoke a bridged tool. A dispatcher is required so the kernel cannot
/// sign successful receipts for simulated side effects.
pub fn invoke_tool(&self, tool_name: &str, arguments: Value) -> Result<Value, BridgeError> {
    // …
    if let Some(dispatcher) = &self.dispatcher {
        // … egress contract checks
        let response = dispatcher(&binding.method, &url, &arguments)?;
        // …
    } else {
        Err(BridgeError::Kernel(
            "OpenAPI bridge requires a dispatcher for live tool invocation".to_string(),
        ))
    }
An illustrative deployment. The host, not Chio, enforces the cut: it decides which processes run and which credentials, handles, and mounts they receive. An embedded library cannot isolate itself from a compromised host.Architecture

Chio's consumer boundary ledger sorts every accepted way to reach the kernel into six profiles, by who dispatches the effect:

  • Trusted native host. The embedding host's own process, through the kernel's native construction path.
  • Mediated protocol. The configured kernel, behind an authenticated MCP, A2A, or ACP-Client edge.
  • Ordinary kernel host. The kernel, built by a factory that installs no active defense.
  • Caller transport. The caller-side executor, once the kernel commits dispatch; Caller delivery covers its reservation, start, and report calls.
  • Portable verification. No one; a portable evaluator decides and never dispatches.
  • Harness. A synthetic or local connector, never a production path.

These are consumer profiles. The six security profiles are a separate vocabulary that sorts execution boundaries by what each controls.

The inventory names 31 constructor sites and 91 dispatch sites

formal/adapter-source-inventory.toml (schema chio.adapter-source-inventory.v1) names every place the workspace may build a kernel and every place a built kernel may evaluate or authorize a tool call, decide a provider invocation, or reserve, start, or reconcile a caller delivery. Dispatch sites cluster where the trust boundary is highest: 42 in chio-kernel, 12 in chio-mcp-edge, 8 in chio-control-plane, and 4 in chio-api-protect, with small counts across the other adapters, tooling, and examples. Each entry records a path, a symbol, a target, and a reference count, grouped by source location.

The check rescans crates, examples, integrations, bench, and sdks for the constructor calls its FACTORIES list names, for direct ChioKernel::new and ChioKernel::default calls (21 of the 31 constructor sites), and for the dispatch calls its prefix list names. Its CALL_CONTRACTS table also requires named protocol-adapter, kernel-validation, and runtime-admission functions to call a named validation or dispatch target a minimum number of times, so an entry point cannot quietly stop checking peer capabilities. Every Chio release passes the adapter-no-bypass gate before it is tagged. chio release verify --evidence qualification shows its result for the release you run.

An unclassified live site or a stale entry fails the check. When you add a constructor or dispatch path, classify its owner, entrypoint, and effect boundary in the inventory, keep that classification through aliases and generated callsites, and extend the scanner for syntax it does not cover. The contributor qualification page runs the check against a source tree.

Test-only code sits outside the scan, and an import alias, a kernel type alias, or a macro-hidden reference fails the check. The checker supplements dispatch contracts and behavior tests and performs no Rust type checking or macro expansion, so a new constructor alias or macro-hidden construction needs a scanner extension. The inventory is a completeness gate over named sites, not a semantic proof that no other path exists.

Source locations

validate_invocation_features is defined at chio-core-types/src/capability/features.rs:106. The FACTORIES list at xtask/src/adapter_no_bypass/constructors.rs:24, and CALL_CONTRACTS at xtask/src/adapter_no_bypass.rs:198.

Negotiation fixes the semantics a session carries before admission begins

CapabilityNegotiation::validate_invocation_features checks a request's aggregate budget, cumulative approval, threshold-governed approval, governed active-response, and opaque supplemental extensions against the profile the peer negotiated, before any signature or admission check. A request that uses an extension its session never negotiated is refused, and an adapter that drops a negotiated required field is refused instead of downgraded. Success establishes semantic compatibility; signatures, reservations, and authorization are decided afterward. MCP negotiates the profile once, at initialize, in capabilities.experimental.chioAuthorization: an object naming the extensions the session supports.

A declared information flow travels the same way. A manifest-aware entrypoint checks for an installed flow runtime before metadata validation or dispatch, so an ordinary host with no governed flow runtime refuses a flow-required reader with FlowRuntimeUnavailable, while a configured native host with the verified manifest, an atomically installed runtime, and an authenticated request invokes it. Removing the declaration or choosing an ungoverned entrypoint repairs nothing, and the reader's original destination is still evaluated.

Invoke a flow-required reader through the manifest-aware entrypoint
security-host/required_flow_host.rsrust
use chio_kernel::{ChioKernel, KernelError, SecurityInvocationContext,
    ToolCallRequest, ToolCallResponse};
use chio_manifest::{BridgeSecurityMetadata, VerifiedManifestRegistry};

/// Invoke through the actual manifest-aware entrypoint. Its required-runtime
/// check happens before metadata validation or dispatch; the registry and
/// security context are independently authenticated selections of the host.
pub fn invoke_required_flow_reader(
    kernel: &ChioKernel, original: &ToolCallRequest,
    registry: &VerifiedManifestRegistry, security: &BridgeSecurityMetadata,
    current_context: &SecurityInvocationContext,
) -> Result<ToolCallResponse, KernelError> {
    kernel.evaluate_tool_call_blocking_with_manifest_security_and_security_context(
        original, registry, security, None, current_context,
    )
}

/// A readiness observation is useful for diagnosis, but not a dispatch permit.
pub fn check_required_flow_host(
    kernel: &ChioKernel, registry: &VerifiedManifestRegistry,
) -> Result<(), KernelError> {
    if registry.requires_flow_runtime() && !kernel.has_installed_flow_runtime() {
        return Err(KernelError::FlowRuntimeUnavailable);
    }
    Ok(())
}

The first function uses the manifest-aware evaluation entrypoint, whose required-runtime check precedes dispatch, and compiles. The second is an advisory readiness query on the verified registry and runtime generation; it grants no permission and never replaces the invocation. Download the function. For each exposed entrypoint, pair a useful admitted read with a credential-file or public-export request that should refuse: the repository matcher and export comparison run those pure checks, and a deployed host adds its own physical observations.

Every language binding is held to the same wire and the same refusals

Ten more required boundaries, P01 to P10 in the consumer ledger's public profile mapping, extend the inventory to portable evaluators, declarative translators, and effect-only connectors the physical scan does not walk. Nine SDK lanes, S01 to S09, name each language package's role, and feature negotiation, required authority, and failure behavior stay equivalent across them.

  • Current wire. Python S01, TypeScript S04, and Go S06 are held to the shared fixtures by the sdk-parity gate, so a generated model that drifts from the canonical schema fails.
  • Manifest helpers. S02, S05, and S07 recognize v1 only and do not count as current-v2 verification.
  • Rust and bindings. The Rust current-wire corpora and the S08 chio-binding-helpers receipt vectors run in the same sdk-parity gate. Every Chio release passes the sdk-parity gate before it is tagged. chio release verify --evidence qualification shows its result for the release you run.
  • C++. S09 runs its own behavioral gates.

Read more in Behavioral gates, which owns the suite's execution.

Unnegotiated features and flow-required manifests stop before dispatch

An MCP tools/call that uses an unnegotiated feature gets the first refusal inside a JSON-RPC error on the same connection. chio mcp serve-http, chio mcp serve, and chio mcp wrap print the other three to stderr, each with help: run the server under an active-defense host profile, and exit 1 before the edge serves a request or the wrapped server launches.

RefusalCause
JSON-RPC error -32602 "canonical JSON error: invocation feature <feature> was not negotiated"
Call used a feature its session did not negotiate
error[CHIO-CLI-ACTIVE-DEFENSE-REQUIRED]: a flow-required manifest needs an active-defense host, and this remote MCP edge installs no flow runtime
chio mcp serve-http given a flow-required manifest; its ordinary kernel installs no flow runtime
error[CHIO-CLI-ACTIVE-DEFENSE-REQUIRED]: a flow-required manifest needs an active-defense host, and chio mcp serve installs no flow runtime
The same on the stdio chio mcp serve path
error[CHIO-CLI-ACTIVE-DEFENSE-REQUIRED]: a flow-required manifest needs an active-defense host, and chio mcp wrap installs no flow runtime
The same on the wrapping path

For an unnegotiated feature, correct the session's negotiation; negotiation still grants no authority. For a flow-required manifest, run an active-defense host that installs the flow runtime, since dropping the manifest requirement would bypass the declared boundary. Integration maintainers check the same refusal on every transport they expose.

Next: see which threats each control covers