Privacy Mode Enforcement in OpenHuman's Rust Core: A Layered Security Model

OpenHuman's Rust core prevents data leaks by routing every network request through a centralized egress enforcer that reads a globally locked LivePolicy, allowing the system to block outbound traffic in LocalOnly mode without restarting the process.

The tinyhumansai/openhuman repository implements privacy mode enforcement as a first-class security primitive inside its Rust core. Rather than scattering checks across individual tools, the architecture unifies configuration, live-policy management, and egress control into a cohesive pipeline. The following sections break down exactly how the core stores the mode, updates it at runtime, and blocks unauthorized network traffic.

Configuration and RPC Layer

The privacy mode originates in the core configuration schema and remains accessible through stable RPC endpoints.

PrivacyMode Schema Definition

The enum and its defaults live in src/openhuman/config/schema/privacy.rs. This file establishes the valid privacy states—such as Standard and LocalOnly—that the rest of the system consumes.

Runtime Configuration via RPC

External clients read or mutate the mode through the controllers defined in src/openhuman/config/schemas/controllers.rs (lines 428-433). The endpoints openhuman.config_get_privacy_mode and openhuman.config_set_privacy_mode provide the primary interface for runtime inspection and adjustment.

Live-Policy Layer for Runtime Privacy Mode Enforcement

Between persistent configuration and network enforcement sits the LivePolicy, a globally accessible structure that maintains the mutable authority on privacy mode.

Global LivePolicy with RwLock

When the core boots, it creates a LivePolicy that wraps a mutable RwLock<PrivacyMode> (src/openhuman/security/live_policy.rs, lines 31-35 and 50-52). The initial value is seeded from the installed SecurityPolicy field policy.privacy_mode, managed in src/openhuman/security/policy/enforcement.rs through SecurityPolicy::with_privacy_mode and its accessor. Any subsystem can query the active value by calling current_privacy_mode(), which is implemented at lines 156-163 in the live-policy module.

Thread-Local Overrides for Testing

The core supports temporary, thread-local overrides through test_privacy_scope() (src/openhuman/security/live_policy.rs, lines 111-115). This function returns an RAII guard that forces a specific mode for the current thread only, enabling tests or short-lived operations to run under a restricted stance without altering the global LivePolicy.

Hot-Reloading Privacy Mode Without Restart

Administrators can change the privacy mode at runtime via reload_privacy(new_mode) (src/openhuman/security/live_policy.rs, lines 270-306). The implementation clones the current policy, swaps only the privacy_mode field, and atomically re-installs the policy object. Because all readers call current_privacy_mode(), they immediately observe the updated value without requiring a process restart.

Egress Enforcement Layer

Every network-bound operation in the core must pass through a centralized enforcement routine that consults the live policy before transmitting data.

The enforce_egress Entry Point

The canonical check lives in src/openhuman/security/egress/enforce.rs. The function enforce_egress begins by capturing the live value with let mode = current_privacy_mode(); (lines 155-166). When the mode is Standard, the operation proceeds and the core emits a debug log formatted as [privacy][egress-enforce] ... — permitted. When the mode is LocalOnly, the request is rejected and logged as [privacy][egress-enforce] ... — denied (lines 166-193).

Network Tool Integration

All outbound tools invoke this enforcer prior to opening sockets. The modules src/openhuman/tools/impl/network/http_request.rs, src/openhuman/tools/impl/network/curl.rs, and src/openhuman/tools/impl/network/web_fetch.rs contain inline guards such as:

if current_privacy_mode() == PrivacyMode::LocalOnly {
    // block outbound request
}

These files also carry comments referencing privacy epic identifiers (for example, "privacy epic S7, #4441"), linking the enforcement logic back to the original design requirements.

Subsystem Propagation

To guarantee consistency, every major subsystem receives the config-derived mode during startup and forwards it into the live-policy. In src/openhuman/channels/runtime/startup.rs (line 288), the Channels runtime invokes .with_privacy_mode(config.privacy.mode) so that the voice pipeline, TUI, and other components inherit the same privacy stance from the moment they initialize.

Code Examples

The following snippets demonstrate how to query, update, and observe privacy mode enforcement in practice.

Query the current privacy mode over RPC:

let privacy = core_rpc_client
    .invoke("openhuman.config_get_privacy_mode", json!({}))
    .await?;
println!("Current mode: {}", privacy["mode"]); // e.g. "Standard"

Switch to LocalOnly mode over RPC:

core_rpc_client
    .invoke("openhuman.config_set_privacy_mode", json!({ "mode": "local_only" }))
    .await?;

Execute a network request that respects the enforced mode:

let result = tools::network::http_request::execute(
    "GET",
    "https://api.example.com/data",
    /* body */ None,
).await;
// In LocalOnly mode the request is blocked and returns an error.

Summary

Frequently Asked Questions

What is privacy mode enforcement in OpenHuman?

Privacy mode enforcement is the Rust core mechanism that inspects every network-bound operation against a centrally managed PrivacyMode value. When set to LocalOnly, the core blocks all outbound traffic so that user data remains on the device.

How does the Rust core block network requests in LocalOnly mode?

The core blocks requests through the enforce_egress function in src/openhuman/security/egress/enforce.rs. This function calls current_privacy_mode() and, if the result is LocalOnly, logs a denial and prevents the operation from proceeding. Every network tool—including HTTP, curl, and web fetch implementations—invokes this check before opening a connection.

Can privacy mode be changed without restarting the OpenHuman core?

Yes. Administrators can call openhuman.config_set_privacy_mode over RPC, which triggers reload_privacy(new_mode) in src/openhuman/security/live_policy.rs (lines 270-306). The function clones the active policy, updates the privacy_mode field, and re-installs it atomically, so all subsequent checks use the new value immediately.

How do tests override privacy mode without affecting global state?

Tests use the test_privacy_scope() helper from src/openhuman/security/live_policy.rs (lines 111-115). This helper creates a thread-local RAII guard that temporarily forces a specific PrivacyMode for the current thread only, leaving the global LivePolicy unchanged.

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 →