anthropics / anthropics/claude-code

Sandboxing unusable for JVM projects: cannot keep filesystem isolation without network isolation

Abierto
#92,609 0 comentarios 0 reacciones 0 asignados Ver en GitHub
area:sandbox enhancement platform:macos
Lenguaje dominante
Python
Estrellas
145k
Forks
23.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

### Preflight Checklist

- [x] I have searched [existing requests](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20label%3Aenhancement) and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)

### Problem Statement

`sandbox.enabled: true` applies filesystem **and** network isolation together. I wanted the
filesystem half only — confine reads and writes to my project — while leaving network egress
alone. There is no way to do that, and two further problems make sandboxing unworkable for a
JVM project even when egress is nominally allowed.

**Environment:** macOS 15 (Darwin 24.6.0) · Claude Code 2.1.252 · JDK 26.0.2.1 ·
JUnit Jupiter 5.10.0 · Maven

### 1. No counterpart to `sandbox.filesystem.disabled`

`sandbox.filesystem.disabled: true` turns off the filesystem half while keeping network
isolation. There is no equivalent for the network half — no `sandbox.network.disabled`, and
`allowedDomains: ["*"]` still routes traffic through the local proxy rather than bypassing it.

### 2. A JVM cannot connect to the sandbox proxy at all

This looks like a bug rather than a design choice. With the sandbox on, egress goes through a
local filtering proxy. `curl` picks it up from `HTTPS_PROXY` and works:

```console
$ curl -s -o /dev/null -w '%{http_code}\n' https://api.openai.com/v1/models
401
```

A JVM does not. `java.net.http.HttpClient` ignores the proxy environment variables, and setting
`-Dhttps.proxyHost` / `-Dhttps.proxyPort` does not help either, because the JVM cannot open a
socket to the proxy in the first place:

```java
new Socket().connect(new InetSocketAddress("localhost", 65195), 3000);
// java.net.SocketException: Operation not permitted
```

A JVM application is therefore cut off from the network entirely while sandboxed, regardless of
`allowedDomains`.

### 3. `@TempDir` fails because `java.io.tmpdir` is outside the writable set

The JVM's default `java.io.tmpdir` on macOS is `/var/folders/…/T/`, which is not among the
sandbox's writable paths, while `$TMPDIR` is set to a sandbox-managed directory
(`/tmp/claude-501`). Every JUnit test using `@TempDir` fails before it runs:

```text
ExtensionConfigurationException: Failed to create default temp directory
Caused by: java.nio.file.FileSystemException:
/var/folders/…/T/junit17117448255593413468: Operation not permitted
```

33 of my 39 unit tests failed this way until I added `-Djava.io.tmpdir="$TMPDIR"`. The
workaround is simple once known, but nothing in the failure suggests sandboxing is the cause.

### Net effect

Under sandboxing I could compile and run 39 unit tests (after the `java.io.tmpdir` workaround)
but not the integration tests that call an LLM API. I disabled sandboxing altogether and fell
back to `permissions.blockReadsOutsideWorkingDirectories`, losing the containment I wanted —
that setting restricts only the file tools (Read, Grep, Glob), not Bash.

### Proposed Solution

Any one of these would unblock the case; the first two are the smallest changes.

### 1. Let sandboxed processes reach the proxy port

Permit connections to the sandbox's own proxy from inside the sandbox. Runtimes that ignore
`HTTPS_PROXY` could then be pointed at it explicitly:

```bash
java -Dhttps.proxyHost=localhost -Dhttps.proxyPort=$PORT …
```

This needs no new setting and would make the sandbox usable for JVM, and any other runtime that
does not read proxy environment variables.

### 2. Propagate `TMPDIR` into `java.io.tmpdir`, or document the flag

Exporting `TMPDIR` at process launch already makes the JVM adopt it as `java.io.tmpdir`, so this
may just be an env-propagation gap. Failing that, a line in the sandboxing docs would save the
next person the same half-hour:

```bash
java -Djava.io.tmpdir="$TMPDIR" …
```

### 3. Add `sandbox.network.disabled`

A counterpart to the existing `sandbox.filesystem.disabled`, so the two halves can be chosen
independently:

```json
{
"sandbox": {
"enabled": true,
"network": { "disabled": true },
"filesystem": {
"allowWrite": ["/path/to/project"],
"denyRead": ["/Users/me"],
"allowRead": ["/path/to/project", "~/.m2", "~/Library/Java"]
}
}
}
```

Filesystem containment is the part most users are after; network filtering is a separate concern
and, for a local development machine behind a firewall, often not wanted at all.

### Alternative Solutions

_No response_

### Priority

High - Significant impact on productivity

### Feature Category

CLI commands and flags

### Use Case Example

Included above

### Additional Context

Included above

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Start by tracing the sandbox.enabled, sandbox.filesystem.disabled, allowedDomains, and process-launch behavior described in the report. Reproduce the JVM proxy connection and @TempDir failures, then determine which behavior is covered by the existing sandbox settings. Done should leave filesystem-only isolation usable for JVM projects, with documented or supported temporary-directory handling and a clear network-isolation choice.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
java, python
Área
cli, operating-systems, security
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Activo
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.