How the OpenHuman Desktop Tauri Shell Launches and Manages the Embedded Rust Core Process

The OpenHuman desktop client embeds its Rust-based business logic server as an in-process Tokio task within the Tauri shell, using a CoreProcessHandle to manage lifecycle, port allocation, and secure bearer token authentication.

The OpenHuman application uses Tauri as its Rust-based desktop host, embedding the core business-logic server directly within the same process rather than as an external sidecar. This architecture eliminates inter-process communication overhead while maintaining strict lifecycle management through dedicated async handlers and secure token-based authentication.

Core Lifecycle Architecture with CoreProcessHandle

The file app/src-tauri/src/core_process.rs defines the CoreProcessHandle struct, which serves as the primary controller for the embedded core. This struct owns:

  • A Tokio task that runs the embedded JSON-RPC server
  • A cancellation token for graceful shutdown signals
  • A restart lock to serialize concurrent restart attempts
  • The preferred HTTP port and the active port the server currently occupies
  • A generated 256-bit bearer token (rpc_token) required for every RPC request

The bearer token is generated via generate_rpc_token() (lines 45-55) using cryptographically secure random bytes, then stored in a lazily-initialized RwLock named CURRENT_RPC_TOKEN.

// https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_process.rs#L45-L55
pub fn generate_rpc_token() -> String {
    use rand::RngCore as _;
    let mut bytes = [0u8; 32];
    rand::rng().fill_bytes(&mut bytes);
    hex::encode(bytes)
}

Launching the Embedded Core Process

When the UI requires the core (during startup or user-initiated restarts), the Tauri command ensure_running is invoked from app/src-tauri/src/lib.rs. This command implements a robust startup sequence:

  1. Port Verification: Checks whether a process is already listening on the configured port
  2. Identity Probe: Sends GET / to verify the listener is an OpenHuman core
  3. Stale Process Cleanup: Terminates stale cores (left from previous dev sessions) via SIGTERM followed by force-kill if necessary
  4. Fresh Spawn: Calls CoreProcessHandle::ensure_running to spawn a new Tokio task

The environment variable OPENHUMAN_CORE_REUSE_EXISTING=1 can disable the cleanup policy, allowing the UI to attach to any existing listener. The core is started by calling openhuman_core::core::jsonrpc::run_server_embedded_with_ready, receiving the rpc_token in-memory to keep the secret out of process listings.

// https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/lib.rs#L320-L340
async fn start_core_process(
    state: tauri::State<'_, core_process::CoreProcessHandle>,
) -> Result<core_process::RecoveryOutcome, String> {
    log::info!("[core] start_core_process: command invoked from frontend");
    // …
    core_process::CoreProcessHandle::ensure_running(&state).await
}

Secure Authentication via In-Memory Bearer Tokens

Security is maintained through an in-memory token system. The generate_rpc_token() function creates a 256-bit hex-encoded secret that resides only in the CURRENT_RPC_TOKEN RwLock. This token is never exposed through environment variables, preventing leakage via process inspection.

The Tauri command core_rpc_token in app/src-tauri/src/core_rpc.rs (lines 13-19) exposes this token to the JavaScript renderer:

// https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs#L13-L19
let token = crate::core_process::current_rpc_token();

The frontend stores this token in memory and includes it as Authorization: Bearer <token> on every HTTP/JSON-RPC request, ensuring only the Tauri host and authorized renderer can access the embedded core.

Restart and Graceful Shutdown Management

The frontend can request a core restart via the restart_core_process command in app/src-tauri/src/lib.rs (lines 348-365). This operation follows a strict serialization protocol:

  • Acquires the restart_lock (a Mutex<()>) to guarantee only one restart executes concurrently
  • Triggers the existing task's CancellationToken for graceful shutdown
  • Waits for the old task to exit before spawning a new instance with a fresh bearer token
// https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/lib.rs#L348-L365
async fn restart_core_process(
    state: tauri::State<'_, core_process::CoreProcessHandle>,
) -> Result<core_process::RecoveryOutcome, String> {
    log::info!("[core] restart_core_process: command invoked from frontend");
    // …
    core_process::CoreProcessHandle::restart(&state).await
}

Handling Port Conflicts and Fallback Logic

When the preferred port is occupied by an unknown process, the recover_port_conflict function (lines 720-770 in core_process.rs) implements port fallback. It selects a free port, records a PortFallbackNotice, and updates the active_port field. The port_fallback Tauri command exposes this information to the UI, allowing the interface to notify users of the port change.

Frontend Integration Examples

Starting the Core from TypeScript

import { invoke } from '@tauri-apps/api/tauri';

// Request the Tauri host to start the core
await invoke('start_core_process');

Restarting After Configuration Changes

await invoke('restart_core_process');

Authenticating API Requests

const token = await invoke<string>('core_rpc_token');
await fetch(`${baseUrl}/rpc`, {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}` },
  body: JSON.stringify(payload),
});

Handling Port Fallback Notifications

const fallback = await invoke<{
  preferred_port: number;
  chosen_port: number;
}>('port_fallback');
if (fallback) {
  console.warn(
    `Preferred port ${fallback.preferred_port} was occupied – using ${fallback.chosen_port}`
  );
}

Summary

  • In-Process Architecture: The OpenHuman core runs as a Tokio task within the Tauri process, eliminating external binary management.
  • Lifecycle Control: CoreProcessHandle in app/src-tauri/src/core_process.rs manages spawning, shutdown, and restart serialization via restart_lock and CancellationToken.
  • Security Model: generate_rpc_token() creates 256-bit secrets stored in CURRENT_RPC_TOKEN, exposed only through the core_rpc_token command for in-memory browser access.
  • Port Resilience: The recover_port_conflict function handles occupied ports by selecting alternatives and notifying the UI via port_fallback.
  • Stale Process Cleanup: The startup routine identifies and terminates orphaned core processes before spawning fresh instances, unless OPENHUMAN_CORE_REUSE_EXISTING=1 is set.

Frequently Asked Questions

How does OpenHuman prevent port conflicts when starting the core?

The ensure_running command in app/src-tauri/src/lib.rs probes the configured port before startup. If occupied by a non-OpenHuman process, the recover_port_conflict function (lines 720-770 in core_process.rs) automatically selects an available port and records a PortFallbackNotice for the UI.

What security mechanism protects the embedded core's JSON-RPC API?

All RPC requests must present a 256-bit bearer token generated by generate_rpc_token() and stored in the CURRENT_RPC_TOKEN RwLock. This token is passed in-memory to the embedded core and exposed to the renderer only through the core_rpc_token command, never via environment variables or command-line arguments.

How does the Tauri shell handle stale core processes from previous sessions?

During startup, the start_core_process command sends a probe to any existing port listener. If a stale OpenHuman core is detected, the system attempts graceful termination via SIGTERM, followed by force-kill if necessary. This cleanup can be disabled by setting OPENHUMAN_CORE_REUSE_EXISTING=1.

Can the desktop UI connect to an externally running core instance?

Yes, by setting the environment variable OPENHUMAN_CORE_REUSE_EXISTING=1, the Tauri shell skips process cleanup and attaches to any existing listener on the configured port. This allows developers to connect the UI to externally launched core instances during development or debugging scenarios.

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 →