Skip to content

OpenSandbox

vserver/v0.2.2 Security

This release includes 3 security fixes for security teams reviewing exposed deployments.

βœ“ No known CVEs patched
Read the diff β†’ Tool health β†’ What is this tool? β†’
This release patches 3 known CVEs

Topics

ai ai-agent ai-infra kubernetes sandbox

Affected surfaces

auth breaking_upgrade

Summary

AI summary

Updates πŸ“¦ Misc, πŸ› Bug Fixes, and ✨ Features across a mixed release.

Full changelog

What's New

⚠️ Breaking Changes

  • Credential Vault requires dns+nft enforcement β€” DNS-only egress can no longer carry credential-bound traffic. Migrate to [egress] mode = "dns+nft"; defaultAction: allow still works but is deprecated and warns. #1136

  • X-Forwarded-Proto no longer trusted by default β€” the server proxy strips client-supplied forwarded headers and rebuilds them from the connection. Deployments that terminate TLS in front of the egress sidecar must list their proxy addresses in the new OPENSANDBOX_EGRESS_CREDENTIAL_VAULT_TRUSTED_PROXY_CIDRS. #1138

  • OPENSANDBOX_EGRESS_MITMPROXY_SCRIPT removed from the env allowlist β€” the variable let a sandbox point the egress sidecar's mitmdump -s at any file under the shared /opt/opensandbox emptyDir, enabling code execution in the sidecar and Credential Vault plaintext access. Requests carrying it are now rejected. Ship custom addons in a purpose-built egress image via ENV. #1194

πŸ”’ Security

  • Secure-access token now enforced on the server proxy β€” the lifecycle proxy at /sandboxes/{id}/proxy/{port}/... previously skipped API-key checks and never validated the OpenSandbox-Secure-Access header (CVSSv3.1 ~7.5). Both HTTP and WebSocket paths now require a matching header (constant-time compare) and strip the token before forwarding. #1191

  • Sandbox pods no longer mount a service-account token β€” the kubernetes.service_account config is removed and automountServiceAccountToken: false is set on both providers. Nothing in the sandbox consumed the token. Operators depending on the SA's imagePullSecrets should move serviceAccountName into their agent-sandbox template. #1227

  • 21 CVE-remediating dependency bumps β€” pydantic-settings, python-multipart, starlette, cryptography, pyjwt, undici, js-yaml. Direct deps pinned in pyproject.toml, transitives via [tool.uv] constraint-dependencies and pnpm.overrides. #1145

✨ Features

  • Multi-tenancy provider with file and HTTP backends β€” sandboxes and snapshots can be isolated per tenant via K8s namespaces. Ships a file provider (TOML with mtime hot-reload) and an HTTP provider (per-key TTL cache + singleflight). Tenant context is propagated per request through auth middleware; unavailable providers return 503. Closes #972 #497. #1184

  • sandbox.create latency reported via metrics events β€” new POST /v1/metrics/events accepts fire-and-forget MetricsEvent payloads and optionally records them as an OTEL histogram (opensandbox.sandbox.create.duration). Python/Go/JS SDKs already hook this on every create. Configure via [otel]. #1307

  • Sandbox extensions returned in lifecycle responses β€” CreateSandboxResponse, getSandbox, and listSandboxes now surface opensandbox.extensions.* back to callers, matching the values set at create time. K8s reads from pod annotations; Docker persists them as container labels. Closes #1060. #1112 #1167

  • Snapshot list supports exact-name filtering β€” GET /snapshots accepts an optional name query parameter, honored through the API, service, and SQLite repository while preserving pagination. Exposed in the Python, JavaScript, Go, C#, and Kotlin SDKs. Closes #1205. #1301

  • Configurable Docker port range for bridge-mode sandboxes β€” new [docker] port_range_min / port_range_max fields (default 40000-60000) narrow host-port allocation so multiple bridge-mode sandboxes can expose distinct execd ports (host mode always binds 44772). #1182

  • OPENSANDBOX_EGRESS_POLICY_FILE and OPENSANDBOX_EGRESS_SANDBOX_ID now allowlisted β€” sandbox creates can opt into egress policy-file persistence and per-sandbox OTLP attribution (OSEP-0010) via the standard env field. #1190 #1335

  • JDK trust store hardened for MITM CA β€” bootstrap.sh now discovers every JDK on the system and imports the egress MITM CA into each cacerts via keytool. Fixes PKIX failures on tarball / Alpine / distroless JDKs when using the credential proxy. Idempotent and best-effort. Closes #1201. #1229

πŸ› Bug Fixes

  • Docker listSandboxes no longer flakes on concurrent deletion β€” docker-py's high-level containers.list() does a follow-up inspect per match, so a sibling cleanup mid-listing failed the whole call with 500. The service now uses the low-level docker_client.api.containers(...) summary endpoint and maps NotFound from single-container lookups to 404. List view drops entrypoint, exit code, and FinishedAt fidelity (callers needing those must use getSandbox). #1342

  • K8s informer honors informer_resync_seconds β€” periodic full resync was silently disabled while watch mode was active. Watch streams are now capped by the remaining resync interval. Fixes #1322. #1323

  • networkPolicy rejected in pool mode β€” combining extensions.poolRef with a networkPolicy is unsupported; requests are now rejected at schema validation with a defense-in-depth guard in BatchSandboxProvider. Closes #1315. #1319

  • Diagnostics scoped to the tenant namespace β€” K8s pod/log/event lookups use the request-scoped tenant namespace instead of the server default. Non-tenant requests unchanged. Closes #1304. #1305

  • use_server_proxy preserves the API mount prefix β€” the API is mounted both bare and under /v1, but proxied endpoints were derived from request.base_url and dropped the prefix, breaking ingress deployments that path-split /v1/*. The rewritten endpoint now keeps the prefix; server.eip is still respected verbatim. #1297

  • Renewed Docker sandbox expirations survive restart β€” timers were rebuilt from immutable container labels, so a renewed sandbox reverted to its original TTL. Renewals now write an override into the file-backed metadata store; old callbacks that observe a renewal rearm cleanly. Closes #1200. #1267

  • PVC readOnly propagated to the volume source β€” the flag was only applied to the mount, not to persistentVolumeClaim.readOnly on the pod spec. Both are now aligned. Closes #545. #1246

  • Fail fast for missing poolRef pools β€” extensions.poolRef is validated against the Pool CRD before creating a BatchSandbox, returning KUBERNETES::POOL_NOT_FOUND instead of failing downstream. Fixes #1175. #1176

  • Docker egress no longer crashes on hosts without IPv6 procfs entries β€” egress.disable_ipv6=true unconditionally injected net.ipv6.conf.*.disable_ipv6 sysctls. The injection is now skipped when the required procfs knobs are missing. Fixes #1168. #1172

  • Event loop no longer blocked during Docker image pull β€” provisioning runs on a daemon thread with an asyncio.Future so health checks stay responsive. New timeout_graceful_shutdown config (default 5s) makes SIGINT actually exit. #1171

  • K8s diagnostics logs endpoint works on multi-container pods β€” read_namespaced_pod_log was called without a container argument, so every standard sandbox (with egress sidecar + execd-installer init) returned 500. The endpoint now defaults to the sandbox container, accepts ?container= for sidecar/init logs, and maps K8s errors to structured 400/403/404/502. Fixes #1150. #1151

πŸ“¦ Misc

  • renew_intent marked stable β€” OSEP-0009 is out of experimental; drops [EXPERIMENTAL] / πŸ§ͺ markers from config docstrings, example TOML, startup logs, and configuration.md. No behavior change. #1350

  • Removed unused PendingSandbox machinery and fixed the spec β€” Docker and K8s both provision synchronously; the async worker, related helpers, and their tests were dead code (βˆ’357 lines). The POST /sandboxes 202 response description in specs/sandbox-lifecycle.yml also described a Pending β†’ Running polling flow that was never implemented β€” now corrected. #1178

  • GHCR image publishing β€” component images (server, k8s, execd, egress, ingress) are now published to GitHub Container Registry alongside Docker Hub and Aliyun. Refs #1160. #1161

  • Package metadata and docs point at opensandbox-group/OpenSandbox β€” user-facing links across README, docs, Helm chart, examples, and server/cli pyproject.toml updated. No package rename. #1197 #1140

  • Auto-bumps β€” execd v1.0.20 β†’ v1.0.21 (#1144 #1279); egress v1.1.3 β†’ v1.1.4 (#1142 #1278).

πŸ‘₯ Contributors

Thanks to these contributors ❀️

  • @1363653611
  • @bcho
  • @FAUST-BENCHOU
  • @ferponse
  • @GreenShadeZhang
  • @Gujiassh
  • @hellomypastor
  • @jianpingpei
  • @jwx0925
  • @Pangjiping
  • @ruirui6946
  • @shenshouer
  • @tea-artist

  • PyPI: opensandbox-server==0.2.2
  • Docker Hub: opensandbox/server:v0.2.2
  • Aliyun Registry: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/server:v0.2.2
  • GHCR: ghcr.io/opensandbox-group/server:v0.2.2

Breaking Changes

  • Credential Vault requires `dns+nft` enforcement; DNS‑only egress is no longer allowed (migrate to `[egress] mode = "dns+nft"`).
  • `X-Forwarded-Proto` header is stripped by default and must be rebuilt; deployments terminating TLS in front of the sidecar need to add proxy CIDRs to `OPENSANDBOX_EGRESS_CREDENTIAL_VAULT_TRUSTED_PROXY_CIDRS`.
  • Removed env var `OPENSANDBOX_EGRESS_MITMPROXY_SCRIPT` from allowlist; requests carrying it are now rejected.

Security Fixes

  • Secure‑access token enforcement added to server proxy on HTTP and WebSocket paths (CVE not listed, CVSSv3.1 ~7.5).
  • Sandbox pods no longer mount a Kubernetes service‑account token; operators must move `serviceAccountName` into their agent template.
  • 21 dependency bumps remediating CVEs: pydantic-settings, python-multipart, starlette, cryptography, pyjwt, undici, js-yaml.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track OpenSandbox

Get notified when new releases ship.

Sign up free

About OpenSandbox

Secure, Fast, and Extensible Sandbox runtime for AI agents.

All releases β†’

Related context

Earlier breaking changes

Beta — feedback welcome: [email protected]