Skip to content

Releases: cloudflare/sandbox-sdk

@cloudflare/sandbox@0.12.2

25 Jun 17:53
5c20455

Choose a tag to compare

Patch Changes

  • #778 b48fa30 Thanks @aron-cf! - Disable the default session for bridge command and file requests. Calls without Session-Id now run without reusing shell state; pass Session-Id from the session API to preserve working directory or environment across calls.

@cloudflare/sandbox@0.12.1

09 Jun 14:43
48f3f4f

Choose a tag to compare

Patch Changes

  • #748 ab6206a Thanks @ghostwriternr! - Recover automatically from transient infrastructure failures when the SDK opens its WebSocket control connection to a sandbox. Previously, any 5xx response other than 503 on the upgrade would fail the SDK call even when the container was healthy.

@cloudflare/sandbox@0.12.0

08 Jun 16:01
9c6de51

Choose a tag to compare

Minor Changes

  • #739 9b4b1da Thanks @scuffi! - Remove the desktop client API and desktop Docker image variant. The sandbox.desktop APIs, DesktopClient exports, desktop-related types/errors, and -desktop container image are no longer available.

Patch Changes

  • #727 2acbd24 Thanks @scuffi! - Add credentialProxy option to mountBucket to keep real S3 credentials out of the container. When enabled, the Durable Object intercepts and signs outbound S3 requests — the container only sees dummy credentials. Supports S3-compatible endpoints, R2, and GCS HMAC signing, with optimized R2 mount defaults for reliable read and write performance.

  • #736 28b5dfa Thanks @scuffi! - Fix bucket mounts when a Sandbox class defines a catch-all outbound handler by routing SDK-managed mount hosts through the SDK ContainerProxy.

  • #737 93c74e3 Thanks @scuffi! - Fix phantom running processes after a failed startProcess call. When the underlying session was unavailable or threw during startup, the process record was left in memory with status running and would appear in listProcesses() indefinitely. Failed startups are now correctly marked as terminal error records.

@cloudflare/sandbox@0.11.0

01 Jun 14:56

Choose a tag to compare

Minor Changes

  • #708 287ec04 Thanks @ghostwriternr! - Prevent stale preview URLs from waking or reaching sandbox runtimes. Invalid, revoked, or destroyed preview URLs return 404 INVALID_TOKEN; authorized URLs that are not activated for the current runtime return 410 STALE_PREVIEW_URL until the port is exposed again. Existing preview URLs that previously survived container restart now return 410 STALE_PREVIEW_URL after a restart until the port is exposed again in the new runtime.

    getExposedPorts() and isPortExposed() now report only ports that are currently preview-forwardable in the active runtime. unexposePort() is now idempotent: revoking a port that is not currently exposed succeeds without contacting the container. Preview URL state no longer uses the container-local exposed-port registry or proxy routes.

Patch Changes

  • #733 d4a739b Thanks @scuffi! - Allow backup and restore presigned URLs to target non-default R2 endpoints. Set BACKUP_BUCKET_ENDPOINT, for example https://<account_id>.eu.r2.cloudflarestorage.com, when your backup bucket uses an R2 jurisdiction.

  • #732 8b9ec84 Thanks @ghostwriternr! - Add bridge endpoints for managing tunnels to sandbox services. HTTP clients can call POST /v1/sandbox/:id/tunnel/:port with an optional name body field for a predictable named URL, and DELETE /v1/sandbox/:id/tunnel/:port to remove the tunnel.

  • #730 de68927 Thanks @ghostwriternr! - Classify Office Open XML files such as .xlsx and .docx as binary when reading files so they are returned with base64 encoding instead of text decoding.

  • #722 95bb7b9 Thanks @aron-cf! - Add named-tunnel support to sandbox.tunnels.get(port, { name }). Named tunnels bind a user-controlled hostname (<name>.<your-zone>) backed by a Cloudflare Tunnel and a proxied CNAME on your zone, so the URL is stable across container restarts and across sandboxes that share the same name. Calling sandbox.destroy() tears down the Cloudflare tunnel and DNS record alongside the container.

    const tunnel = await sandbox.tunnels.get(8080, { name: 'app' });
    console.log(tunnel.url); // → https://app.example.com

@cloudflare/sandbox@0.10.3

27 May 15:14
537c037

Choose a tag to compare

Patch Changes

  • #715 453b577 Thanks @aron-cf! - Upgrade capnweb to 0.8.0.

  • #714 0ec4f42 Thanks @aron-cf! - Bundle cloudflared into the musl/Alpine images.

  • #706 ae5f9a1 Thanks @scuffi! - Add sessionless execution mode with a configurable default-session policy.

    Set enableDefaultSession: false in SandboxOptions to run implicit top-level operations without a persistent shell — each command gets a fresh process with no shared state. The option is scoped to the sandbox object returned by getSandbox(...); explicit per-call session IDs continue to target that session.

@cloudflare/sandbox@0.10.2

21 May 14:15
3b58a22

Choose a tag to compare

Patch Changes

  • #695 c6bf7dc Thanks @aron-cf! - Add sandbox.tunnels namespace with quick-tunnel support. Call sandbox.tunnels.get(port) to obtain a https://<words>.trycloudflare.com URL that proxies to localhost:<port> inside the sandbox. The call is idempotent: repeated calls for the same port return the same record from per-sandbox Durable Object storage. No Cloudflare account or DNS setup required.

    const tunnel = await sandbox.tunnels.get(8080);
    console.log(tunnel.url);
    // → https://random-words-here.trycloudflare.com
    
    const same = await sandbox.tunnels.get(8080);
    console.log(same.url === tunnel.url); // true
    
    await sandbox.tunnels.list();
    await sandbox.tunnels.destroy(8080); // or destroy(tunnel)
  • #691 3ca24fc Thanks @scuffi! - Add credential-less R2 bucket mounting via egress interception

  • #703 68c8b71 Thanks @aron-cf! - Fix inconsistencies in the sandbox.desktop interface between RPC and HTTP transports

@cloudflare/sandbox@0.10.1

11 May 18:46
a14a524

Choose a tag to compare

Patch Changes

  • #683 718d4e7 Thanks @aron-cf! - readFile now accepts encoding: 'none' on the rpc transport, returning a result whose content is a ReadableStream<Uint8Array> of raw binary data with no base64 encoding or buffering. Mirrors the existing writeFile support for ReadableStream input.

    // Stream a binary file without buffering or base64 overhead (rpc transport only)
    const { content, size, mimeType } = await sandbox.readFile(
      '/workspace/image.png',
      { encoding: 'none' }
    );

@cloudflare/sandbox@0.10.0

07 May 14:57
ac60237

Choose a tag to compare

Minor Changes

  • #659 7c09e87 Thanks @mvanhorn! - Update the default sandbox image runtime from Node.js 20 to Node.js 24 so published images use the current Node.js LTS release. If your workload needs a different Node.js version, build a custom image with the NODE_VERSION Docker build argument.

Patch Changes

  • #679 21a5a2e Thanks @aron-cf! - Fixed createBackup and restoreBackup with localBucket: true failing on the rpc transport for archives larger than ~24 MiB.

  • #659 7c09e87 Thanks @mvanhorn! - Add NODE_VERSION build arg to the Dockerfile, allowing operators to customize the Node.js version used in sandbox container images.

@cloudflare/sandbox@0.9.4

06 May 12:09
2c298eb

Choose a tag to compare

Patch Changes

  • #669 10d3239 Thanks @aron-cf! - Ensure the RPC transport successfully connects once the container has started. This should
    reduce the likelihood of hitting an RPCTransportError: WebSocket upgrade failed: 503 Service Unavailable error when interacting with a sandbox before the container is ready.

@cloudflare/sandbox@0.9.3

05 May 17:15
f03920a

Choose a tag to compare

Patch Changes

  • #666 e8f57c8 Thanks @scuffi! - Speed up backup and restore for larger archives with faster default compression, multipart R2 uploads, and parallel range downloads that write directly into the restored archive.

  • #647 68c4f9b Thanks @aron-cf! - Introduce new rpc transport to consolidate http and websocket transports.

    The intention is to replace http and websocket transports with a single implementation.

    • No sub-request limitations (currently affects the http transport).
    • No limit on write file size (currently affects both http and websocket transports).

    To enable the transport set SANDBOX_TRANSPORT to rpc in your wrangler config.

    A ReadableStream instance can now be passed to sandbox.writeFile() when using the rpc transport to avoid the 32mb file limit.

    {
      fetch(req, env) {
        const sandbox = getSandbox(env.Sandbox, "my-sandbox");
    
        // A ReadableStream can be passed as the content to writeFile().
        sandbox.writeFile("/workspace/archive.tar.gz", req.body);
    
        return new Response("OK");
      }
    }
  • #653 e18ba4d Thanks @ask-bonk! - Surface s3fs mount failures from mountBucket(). Mount errors (bad credentials, wrong bucket name, network failures) now throw S3FSMountError with the underlying s3fs log output, instead of silently returning success and leaving no filesystem attached.

    import { S3FSMountError } from '@cloudflare/sandbox';
    
    try {
      await sandbox.mountBucket('my-bucket', '/mnt/data', {
        endpoint,
        credentials
      });
    } catch (err) {
      if (err instanceof S3FSMountError) {
        // err.message includes the s3fs log tail, e.g. "403 AccessDenied"
      }
    }