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

> OpenHuman's Privacy Mode guarantees on-device inference by blocking all network calls. Discover how this ensures your data stays secure and private, even without a local model.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: how-to-guide
- Published: 2026-08-29

---

**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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/inference/provider/factory.rs). The provider factory receives the current `PrivacyMode` via `crate::openhuman::config::PrivacyMode` and contains a conditional check:

```rust
// 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`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/config/schema/controllers.rs).

### Enabling LocalOnly Mode

```rust
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

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

```

### Testing Blocked Remote Inference

```rust
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 in [`src/openhuman/config/schema/privacy.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/config/schema/privacy.rs) to classify data sensitivity levels.
- The `LocalOnly` variant activates `local_only_blocks` in [`src/openhuman/security/egress/enforce.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/security/egress/enforce.rs), which aborts any network-bound request before I/O occurs.
- The provider factory in [`src/openhuman/inference/provider/factory.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/inference/provider/factory.rs) refuses to instantiate remote providers when `LocalOnly` is active, ensuring inference stays on-device.
- Runtime configuration changes are handled through RPC endpoints in [`src/openhuman/config/schema/controllers.rs`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/security/policy/enforcement.rs) supports hot-swapping via the `reload_privacy` function in [`src/openhuman/security/live_policy.rs`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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.