Security Model
How CloudCLI UI isolates plugins with frontend sandboxing, server process restrictions, secret handling, and path traversal protection.
Plugins run with significant privileges. The host mitigates risk through multiple layers of isolation.
Trust Model
Plugins are trusted code. Installing a plugin is equivalent to running someone's Node.js code on your machine. Only install plugins from sources you trust.
Frontend Isolation
Your frontend module receives only the api object. It cannot access:
- The host's React state or component tree
- Authentication tokens or session cookies
- Other plugins' state or API
- localStorage or sessionStorage of the host app
Frontend modules are loaded via dynamic import() from a Blob URL. Your code runs in the same origin as the host but cannot access the host's module graph. All backend communication must go through api.rpc(), and a plugin can only call its own server.
Server Process Isolation
Plugin server processes receive only four environment variables:
| Variable | Purpose |
|---|---|
PATH | System PATH |
HOME | User home directory |
NODE_ENV | Node environment |
PLUGIN_NAME | Plugin identifier |
All other env vars from the host are stripped. Each plugin server runs in its own Node.js process with isolated memory, CPU, and file descriptors. Servers must bind to 127.0.0.1 only.
Lifecycle control:
- 10-second startup timeout prevents hung initialization
- SIGTERM + 5-second grace period for graceful shutdown
- SIGKILL fallback for unresponsive processes
Secret Management
Secrets live in ~/.claude-code-ui/plugins.json. They are injected as HTTP headers on each RPC request (x-plugin-secret-<key>), meaning they travel over localhost only, are per-request (not in process memory), and each plugin only receives its own secrets. Updated secrets take effect immediately.
Limitations: secrets are not encrypted at rest, not rotated automatically, and not validated by the host.
Installation Security
- Only
https://andgit@URLs accepted - Shallow clones (
--depth 1) - Directory names validated against
/^[a-zA-Z0-9_.-]+$/ - Manifest validated on install and every scan
npm installuses--production --ignore-scripts(no lifecycle scripts)
Asset Serving Security
Path traversal protection ensures served assets stay within the plugin directory. The host resolves the requested path, verifies it's within bounds, and rejects escape attempts. Plugin names are validated against /^[a-zA-Z0-9_-]+$/.
Recommendations
Do: validate RPC inputs, bind to 127.0.0.1, handle errors without leaking paths, document required secrets, keep dependencies minimal.
Don't: store secrets in code, bind to 0.0.0.0, shell out with unsanitized input, access files outside the project path, log secrets.
Known Limitations
| Limitation | Impact |
|---|---|
| Module-type plugins share the host's DOM | Could modify host UI |
| No CPU/memory limits | Could consume excessive resources |
| No filesystem sandboxing | Can access any user-accessible file |
| No network restrictions | Can make any network call |
| Secrets stored in plaintext | Readable by anyone with filesystem access |