How OpenHuman Enforces On-Device Inference with Zero Network Calls Using Privacy Mode

OpenHuman's Privacy Mode enforces on-device inference by blocking all outbound network traffic when set to LocalOnly, ensuring model execution never leaves the device even if no local model exists.

The OpenHuman runtime provides a Privacy Mode feature that guarantees sensitive data never leaves the local machine during AI inference. By configuring the mode to LocalOnly, the system activates strict egress filters that prevent any network calls to external model providers. This implementation ensures complete on-device processing through a combination of compile-time policy definitions and runtime enforcement checks.

Understanding the Privacy Mode Architecture

The enforcement mechanism relies on three tightly coupled components that work together to guarantee zero network exposure.

The PrivacyMode Enum and Configuration Schema

At the core of the system is the PrivacyMode enum defined in src/openhuman/config/schema/privacy.rs. This enum specifies three distinct privacy levels: Standard, Sensitive, and LocalOnly. The LocalOnly variant triggers the strictest security posture by mandating that all inference operations occur without external network access.

The SecurityPolicy Live Policy System

The runtime maintains a process-wide SecurityPolicy struct located in src/openhuman/security/policy/enforcement.rs. This policy holds the current privacy_mode value and can be hot-swapped at runtime via the reload_privacy function in src/openhuman/security/live_policy.rs. The live policy system ensures that privacy settings take effect immediately without requiring a process restart.

How Network Egress is Blocked

When LocalOnly mode is active, the system intercepts all potential network exit points before any I/O occurs.

The local_only_blocks Enforcement Function

The primary enforcement logic resides in src/openhuman/security/egress/enforce.rs within the local_only_blocks function. This function returns true only when the current mode is LocalOnly and the egress descriptor is marked as external. If both conditions match, the request aborts immediately, preventing any packet from leaving the device.

Provider Factory Gatekeeping

The inference layer implements additional guards in src/openhuman/inference/provider/factory.rs. The provider factory receives the current PrivacyMode via crate::openhuman::config::PrivacyMode and contains a conditional check:

// src/openhuman/inference/provider/factory.rs
if mode != PrivacyMode::LocalOnly {
    // build remote provider (e.g. OpenAI, Claude, etc.)
}

When the mode equals LocalOnly, the factory skips remote provider instantiation entirely. If no on-device model exists, the request returns an error without emitting network traffic. Higher-level tools like openhuman.tools_impl.network.web_fetch and openhuman.tools_impl.network.http_request also invoke local_only_blocks to verify permissions before executing HTTP calls.

Configuring and Testing Privacy Mode

Developers can interact with Privacy Mode through the RPC interface exposed in src/openhuman/config/schema/controllers.rs.

Enabling LocalOnly Mode

use openhuman_core::client::CoreRpcClient;

let client = CoreRpcClient::new("http://127.0.0.1:...".into())?;
client.invoke("openhuman.config_set_privacy_mode", json!({ "mode": "local_only" }))?;

Verifying the Current Mode

let mode = client.invoke("openhuman.config_get_privacy_mode", json!({}))?;
println!("Current privacy mode: {}", mode["mode"]); // => "local_only"

Testing Blocked Remote Inference

let response = client.invoke(
    "openhuman.inference_chat",
    json!({ "model": "openai:gpt-4o", "prompt": "Hello!" })
);
assert!(response.is_err()); // Fails because LocalOnly blocks external egress

Summary

Frequently Asked Questions

What happens if no on-device model is available when LocalOnly mode is set?

The inference request fails immediately with an error. The provider factory in src/openhuman/inference/provider/factory.rs cannot instantiate a remote provider due to the LocalOnly restriction, and if no local model is registered, the system returns an error without attempting any network connection.

Can Privacy Mode be changed at runtime without restarting the OpenHuman process?

Yes. The SecurityPolicy stored in src/openhuman/security/policy/enforcement.rs supports hot-swapping via the reload_privacy function in src/openhuman/security/live_policy.rs. Users can invoke the openhuman.config_set_privacy_mode RPC endpoint to update settings dynamically.

How do third-party tools and integrations respect the LocalOnly restriction?

All network-capable tools, including openhuman.tools_impl.network.web_fetch and composio integrations, call the local_only_blocks function from src/openhuman/security/egress/enforce.rs before executing requests. This centralized check ensures that even indirect tool calls cannot bypass the privacy policy.

Is there a performance impact when running in Privacy Mode?

The enforcement adds minimal overhead consisting of a single enum comparison per egress check. The local_only_blocks function performs only lightweight pattern matching against the current PrivacyMode, resulting in negligible latency compared to the actual inference computation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →