# PI Desktop Security Features: Plugin Isolation and Policy Enforcement Explained

> Explore PI Desktop security features like plugin isolation and policy enforcement. Learn how Electron sandboxing and manifest policies protect your host system from untrusted code.

- Repository: [Lan/PI-Desktop](https://github.com/vastsa/PI-Desktop)
- Tags: deep-dive
- Published: 2026-09-12

---

**PI Desktop implements a defense-in-depth security model using Electron renderer sandboxing, declarative manifest policies, strict UI timeouts, and cryptographic version locks to isolate untrusted plugin code from the host system.**

PI Desktop is an extensible desktop application framework that treats third-party plugins as potentially hostile code. The `vastsa/PI-Desktop` repository enforces this security posture through a layered architecture that combines process-level isolation with fine-grained access controls. Every plugin operates within a tightly restricted execution environment where network requests, filesystem operations, and UI interactions are explicitly permitted or denied by declarative policies.

## Renderer Sandboxing and Process Isolation

PI Desktop launches all Electron renderer processes with `sandbox: true` to eliminate direct access to Node.js APIs and the host filesystem. This configuration is enforced in [`apps/desktop/electron/main/index.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/index.ts) at line 2633, ensuring that UI code executes in a Chromium sandbox without the ability to spawn child processes or require native modules. The sandboxing prevents plugins from escaping the browser context to access operating system resources, establishing the first line of defense against code injection attacks.

## Trusted Extension Framework and Lifecycle Controls

The trusted-extension framework defined in [`packages/shared/src/trusted-extensions.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/trusted-extensions.ts) governs how extensions register commands, prompt users, and handle events. This layer introduces three critical safety mechanisms:

- **Handler Timeouts**: The constant `TRUSTED_EXTENSION_HANDLER_TIMEOUT_MS` sets a hard limit of **30 seconds** for command execution, preventing infinite loops from freezing the application.
- **UI Prompt Timeouts**: `TRUSTED_EXTENSION_PROMPT_TIMEOUT_MS` enforces a **5-minute** maximum lifetime for all user confirmation dialogs, ensuring that modal windows cannot persist indefinitely.
- **Kernel Version Lock**: The `TRUSTED_EXTENSION_KERNEL_VERSION` constant ensures that sidecar extensions run only against specific, vetted core versions, preventing compatibility exploits.

Extensions are identified by real-path IDs and loaded once per session, with errors reported via `TrustedExtensionDiagnostic` objects for auditability.

## Declarative Network and Filesystem Policies

PI Desktop requires plugins to declare their intended resource access in their manifests. These declarations are parsed and enforced at runtime by the policy engines in the plugin SDK.

### Network Egress Controls

The [`packages/plugin-sdk/src/net-policy.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/net-policy.ts) module evaluates every outbound URL against a whitelist/blacklist declared in the plugin manifest's `net` section. The `isNetUrlAllowed` function checks requests against explicit `allow` and `deny` patterns before permitting network access.

```json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "net": {
    "allow": ["https://api.example.com", "https://static.example.org"],
    "deny": ["*"]
  }
}

```

This configuration blocks all network traffic except to the two specified domains. The `*` wildcard in the `deny` list functions as a default-deny fallback.

### Filesystem Access Restrictions

The [`packages/plugin-sdk/src/fs-policy.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/fs-policy.ts) module parses the `fs` section of the manifest to construct runtime permission sets. Plugins must specify `read` and `write` roots (such as `userSelected` or `workspace`) and glob patterns defining valid scopes.

```json
{
  "fs": {
    "read": { "root": "userSelected", "scope": ["documents/**"] },
    "write": { "root": "workspace", "scope": ["output/**"] }
  }
}

```

Attempts to read outside `documents/**` or write outside `output/**` trigger policy violations and are rejected before reaching the operating system.

## Remote Agent Control Protocol (RACP) Security

For remote management scenarios, [`packages/shared/src/racp.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/racp.ts) and [`packages/agent-host/src/agent-host.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/agent-host/src/agent-host.ts) implement the Remote Agent Control Protocol. This subsystem governs how external agents request approvals, set session permissions, or affect other connected sessions.

The host-side policy can define `approvalLifetimeMs` values that automatically expire remote grants after a specified duration, protecting against long-lived elevated privileges from forgotten or compromised remote sessions.

```typescript
// In agent-host.ts – when a remote session requests a grant
if (this.policy.approvalLifetimeMs) {
  const ttl = this.policy.approvalLifetimeMs;
  // Grant expires after `ttl` milliseconds
}

```

## Runtime Policy Enforcement and Timeouts

When a plugin loads, [`packages/plugin-sdk/src/index.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/index.ts) (lines 9-13) merges the plugin's manifest policies with host-wide constraints. Every network request and file operation is checked against this merged policy before execution.

UI interactions are further constrained by the timeout system in [`packages/shared/src/trusted-extensions.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/trusted-extensions.ts). When an extension triggers a user prompt, the renderer must receive a response within `TRUSTED_EXTENSION_PROMPT_TIMEOUT_MS` (300,000ms) or the request automatically expires.

```typescript
import { trustedExtensionCommandId } from '@pi/shared/trusted-extensions';

// Send a confirm request to the renderer
desktop.sendUiRequest({
  sessionId,
  extensionId,
  extensionLabel,
  request: { kind: "confirm", title: "Delete file?", message: "Are you sure?" }
});

// Handle the response (must finish within TRUSTED_EXTENSION_PROMPT_TIMEOUT_MS)
desktop.onUiResponse((resp) => {
  if (resp.kind === "confirm") {
    // resp.value === true/false
  }
});

```

## Summary

- **Renderer Sandboxing**: Electron processes launch with `sandbox: true` in [`apps/desktop/electron/main/index.ts`](https://github.com/vastsa/PI-Desktop/blob/main/apps/desktop/electron/main/index.ts) to isolate UI code from Node.js and the filesystem.
- **Manifest Policies**: Declarative `net` and `fs` sections in plugin manifests define explicit boundaries enforced by [`net-policy.ts`](https://github.com/vastsa/PI-Desktop/blob/main/net-policy.ts) and [`fs-policy.ts`](https://github.com/vastsa/PI-Desktop/blob/main/fs-policy.ts).
- **Trusted Extension Controls**: The framework enforces 30-second handler timeouts, 5-minute UI prompt timeouts, and kernel version locks via [`packages/shared/src/trusted-extensions.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/trusted-extensions.ts).
- **Remote Session Limits**: RACP policies in [`packages/shared/src/racp.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/racp.ts) and [`agent-host/src/agent-host.ts`](https://github.com/vastsa/PI-Desktop/blob/main/agent-host/src/agent-host.ts) limit approval lifetimes for remote agents.
- **Policy Merging**: [`packages/plugin-sdk/src/index.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/plugin-sdk/src/index.ts) combines plugin-specific and host-wide policies at load time to create a unified enforcement context.

## Frequently Asked Questions

### How does PI Desktop prevent plugins from accessing the filesystem?

PI Desktop strips Node.js APIs from renderer processes through Electron sandboxing and requires plugins to declare filesystem scopes in their manifests. The [`fs-policy.ts`](https://github.com/vastsa/PI-Desktop/blob/main/fs-policy.ts) module parses these declarations and rejects any operation outside the permitted `root` and `scope` boundaries before the request reaches the operating system.

### What happens if a plugin hangs while waiting for user input?

All UI prompts are subject to `TRUSTED_EXTENSION_PROMPT_TIMEOUT_MS` (5 minutes) as defined in [`packages/shared/src/trusted-extensions.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/trusted-extensions.ts). If the user does not respond within this window, the promise automatically rejects, returning control to the host application and preventing indefinite modal locks.

### Can plugins communicate with any server on the internet?

No. The [`net-policy.ts`](https://github.com/vastsa/PI-Desktop/blob/main/net-policy.ts) module enforces a default-deny posture. Plugins must explicitly whitelist domains in their manifest's `net.allow` array, and the `isNetUrlAllowed` function blocks any request not matching these patterns, including DNS rebinding attempts against internal IP ranges.

### How does PI Desktop ensure extension compatibility with the core application?

The `TRUSTED_EXTENSION_KERNEL_VERSION` constant in [`packages/shared/src/trusted-extensions.ts`](https://github.com/vastsa/PI-Desktop/blob/main/packages/shared/src/trusted-extensions.ts) creates a cryptographic lock between the extension and a specific core version. If the running kernel version does not match the extension's compiled target, the plugin is prevented from loading, mitigating API mismatch exploits.