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
- Privacy Mode in OpenHuman uses a three-tier enum (
Standard,Sensitive,LocalOnly) defined insrc/openhuman/config/schema/privacy.rsto classify data sensitivity levels. - The
LocalOnlyvariant activateslocal_only_blocksinsrc/openhuman/security/egress/enforce.rs, which aborts any network-bound request before I/O occurs. - The provider factory in
src/openhuman/inference/provider/factory.rsrefuses to instantiate remote providers whenLocalOnlyis active, ensuring inference stays on-device. - Runtime configuration changes are handled through RPC endpoints in
src/openhuman/config/schema/controllers.rs, allowing hot-swapping of privacy policies without restarts.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →