# Guest-to-Host Path Translation in Claude Desktop Cowork Mode: Implementation Guide

> Learn guest-to-host path translation in Claude Desktop Cowork Mode. This guide details the JavaScript layer implementation and security validations for seamless file access.

- Repository: [Aaddrick/claude-desktop-debian](https://github.com/aaddrick/claude-desktop-debian)
- Tags: how-to-guide
- Published: 2026-04-19

---

**The Claude Desktop Debian implementation converts virtual guest paths like `/sessions/<id>/mnt/<name>` to real host filesystem paths using a pure JavaScript translation layer in [`scripts/cowork-vm-service.js`](https://github.com/aaddrick/claude-desktop-debian/blob/main/scripts/cowork-vm-service.js) that validates mount mappings and prevents directory traversal attacks.**

When running Claude Desktop in **Cowork** mode, file system access is virtualized through mount points that appear under `/sessions/<session-id>/mnt/`. The `aaddrick/claude-desktop-debian` repository implements a robust guest-to-host path translation system to convert these virtual paths into actual host filesystem locations before spawning processes or performing file operations.

## Core Translation Architecture in Cowork Mode

### Understanding the Virtual Path Format

Guest-side paths in Cowork mode follow a strict virtual pattern:

```

/sessions/<session-id>/mnt/<mount-name>[/sub-path]

```

The daemon must detect this format and extract the mount identifier to perform the lookup. According to the source code in [`scripts/cowork-vm-service.js`](https://github.com/aaddrick/claude-desktop-debian/blob/main/scripts/cowork-vm-service.js), the translation system handles three potential mount map keys to accommodate Electron's `ta()` normalization: the raw mount name, a dot-prefixed version, and the name stripped of a leading dot.

### The Mount Map Construction

Before translation can occur, the system builds a **mount map** that correlates virtual mount names to host directories. The `buildMountMap()` function at lines 219-245 constructs this mapping from two sources:

1. **`mountBinds`** – Created by prior calls to `mountPath()` representing the host-side representation of guest binds
2. **`additionalMounts`** – User-supplied mounts filtered through `resolveSubpath()` to ensure they remain inside the user's `$HOME` directory

## Key Translation Functions

### translateGuestPath(): Converting Virtual to Host Paths

The core translation logic resides in `translateGuestPath(guestPath, mountMap)` at lines 162-196 of [`scripts/cowork-vm-service.js`](https://github.com/aaddrick/claude-desktop-debian/blob/main/scripts/cowork-vm-service.js). This pure function implements a four-stage pipeline:

```javascript
/**
 * Translate a VM guest path (/sessions/{id}/mnt/{name}[/rest]) to a host
 * path using mountMap. Returns the translated path, or null on failure.
 */
function translateGuestPath(guestPath, mountMap) {
    // 1. Input validation
    if (!guestPath.startsWith('/sessions/') || !mountMap || Object.keys(mountMap).length === 0) {
        return null;
    }
    
    // 2. Regex extraction
    const match = guestPath.match(/^\/sessions\/[^/]+\/mnt\/([^/]+)(\/.+)?$/);
    if (!match) return null;
    
    const mountName = match[1];
    const remainder = match[2] || '';
    
    // 3. Mount lookup with fallback keys
    let hostBase = mountMap[mountName] || 
                   mountMap['.' + mountName] || 
                   mountMap[mountName.replace(/^\./, '')];
    
    if (!hostBase) return null;
    
    // 4. Path construction and traversal safety
    const hostPath = path.resolve(path.join(hostBase, remainder));
    if (!hostPath.startsWith(hostBase)) {
        return null; // Directory traversal attack prevented
    }
    return hostPath;
}

```

### buildSpawnEnv(): Translating Environment Variables

The `buildSpawnEnv()` function at lines 76-88 handles environment variable translation, specifically targeting `CLAUDE_CONFIG_DIR` and `CLAUDE_COWORK_MEMORY_PATH_OVERRIDE`. When these variables contain guest paths starting with `/sessions/`, the function invokes `translateGuestPath()` to convert them to host paths before spawning the process.

### cleanSpawnArgs(): Rewriting CLI Arguments

Command-line arguments undergo translation via `cleanSpawnArgs()` (referenced in `tests/cowork-path-translation.bats` at lines 46-63). This function specifically processes:

- **`--add-dir`** flags containing guest mount paths
- **`--plugin-dir`** flags (with additional `resolvePluginRoot()` resolution)
- **`--allowedTools`** arguments containing embedded guest paths

The translation ensures that tools like `Bash(/sessions/abc/mnt/project/script.sh)` become `Bash(/home/user/project/script.sh)` before execution.

## Security and Safety Mechanisms

### Directory Traversal Prevention

The translation layer implements strict path canonicalization using `path.resolve()` followed by a prefix check. After joining the host base with the remainder sub-path, the code verifies that the resolved path still starts with the original host base directory. Any attempt to escape via `../` sequences results in the function returning `null`, preventing access to sensitive host directories.

### Mount Point Validation

The `buildMountMap()` function enforces containment policies for user-supplied mounts. When processing `additionalMounts`, each path undergoes `resolveSubpath()` validation to ensure it resolves within the user's `$HOME` directory. This prevents the daemon from exposing arbitrary host system paths to the guest environment.

## Practical Implementation Examples

### Example 1: Basic Path Translation

```javascript
const { translateGuestPath } = require('./scripts/cowork-vm-service');

const mountMap = {
    project: '/home/alice/projects/my-app',
    '.auto-memory': '/home/alice/.auto-memory'
};

const guestPath = '/sessions/12345/mnt/project/src/index.js';
const hostPath = translateGuestPath(guestPath, mountMap);

console.log(hostPath);
// Output: /home/alice/projects/my-app/src/index.js

```

This demonstrates how the virtual file [`src/index.js`](https://github.com/aaddrick/claude-desktop-debian/blob/main/src/index.js) inside the guest session resolves to its real location on the host filesystem.

### Example 2: CLI Argument Sanitization

When the Electron front-end requests a spawn operation:

```bash
claude-cli spawn \
    --add-dir /sessions/abcde/mnt/project \
    --plugin-dir /sessions/abcde/mnt/.plugins \
    --allowedTools "Bash(/sessions/abcde/mnt/project/script.sh)"

```

The daemon processes these through `cleanSpawnArgs()` and `translateEmbeddedGuestPaths()`:

```javascript
const cleanArgs = cleanSpawnArgs(rawArgs, mountMap);
// Result:
// [
//   '--add-dir', '/home/alice/projects/my-app',
//   '--plugin-dir', '/home/alice/.plugins',
//   '--allowedTools', 'Bash(/home/alice/projects/my-app/script.sh)'
// ]

```

### Example 3: Environment Variable Handling

The front-end may set session-specific configuration:

```env
CLAUDE_CONFIG_DIR=/sessions/xyz/mnt/.claude

```

Before spawning the subprocess, `buildSpawnEnv()` performs the translation:

```javascript
const translatedEnv = buildSpawnEnv(
    { CLAUDE_CONFIG_DIR: '/sessions/xyz/mnt/.claude' }, 
    mountMap
);
// translatedEnv.CLAUDE_CONFIG_DIR === '/home/alice/.claude'

```

This ensures Claude Code reads its per-session configuration from the correct host directory.

## Summary

- Guest-to-host path translation in Cowork mode converts virtual paths (`/sessions/<id>/mnt/<name>`) to real host filesystem locations using a pure JavaScript implementation in [`scripts/cowork-vm-service.js`](https://github.com/aaddrick/claude-desktop-debian/blob/main/scripts/cowork-vm-service.js).
- The **mount map** construction combines automatic bind mounts from `mountPath()` calls with user-supplied `additionalMounts`, enforcing containment within `$HOME`.
- **`translateGuestPath()`** performs regex extraction, mount lookup with fallback keys, and canonicalization with traversal protection using `path.resolve()` and prefix verification.
- Translation applies to **environment variables** (`CLAUDE_CONFIG_DIR`, `CLAUDE_COWORK_MEMORY_PATH_OVERRIDE`), **CLI arguments** (`--add-dir`, `--plugin-dir`), and **embedded tool paths** (`--allowedTools`).
- Comprehensive test coverage in `tests/cowork-path-translation.bats` validates the translation logic against regression.

## Frequently Asked Questions

### How does the translation system prevent directory traversal attacks?

The `translateGuestPath()` function uses `path.resolve()` to canonicalize the joined host base and sub-path, then verifies that the resulting path starts with the original host base directory. If the resolved path attempts to escape via `../` sequences, the function returns `null`, blocking access to sensitive host directories.

### What environment variables get translated during Cowork mode execution?

The system specifically translates `CLAUDE_CONFIG_DIR` and `CLAUDE_COWORK_MEMORY_PATH_OVERRIDE` when they contain guest-style paths starting with `/sessions/`. The `buildSpawnEnv()` function handles these conversions to ensure the spawned processes receive valid host filesystem paths.

### Where can I find the test suite for path translation logic?

The automated test suite resides in `tests/cowork-path-translation.bats`. These Bats tests exercise the pure JavaScript translation helpers in isolation, validating regex extraction, mount lookup logic, and security constraints against regression.

### How does the system handle plugin directory paths differently from standard mount paths?

While `--add-dir` flags undergo direct translation through `cleanSpawnArgs()`, `--plugin-dir` flags receive additional processing via `resolvePluginRoot()`. This extra resolution step determines the actual plugin root directory on the host before the path is passed to the spawn helper, accommodating the specific directory structure requirements of Claude Desktop plugins.