Skip to content

fix(opensandbox): send the API key on proxied execd routes - #2462

Merged
hemildesai merged 1 commit into
mainfrom
hemil/opensandbox-proxy-auth-header
Aug 10, 2026
Merged

hemildesai merged 1 commit into
mainfrom
hemil/opensandbox-proxy-auth-header

Conversation

@hemildesai

@hemildesai hemildesai commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

On OpenSandbox deployments that enforce API-key auth on the server's /proxy/* routes, every proxied execd request fails with 401 {"code":"MISSING_API_KEY"} even though api_key is configured — because the SDK wires the key only into the lifecycle-API clients. The execd-facing clients (health ping, commands, filesystem) send only ConnectionConfig.headers, which the provider never populated.

The visible symptom is nasty: Sandbox.create returns 202, endpoint lookups return 200, but the SDK's internal health wait pings /proxy/44772/ping keyless, gets 401 forever, and creation spins until ready_timeout before failing with SandboxReadyTimeoutException. Exec and file operations through the proxy fail the same way.

Change

In _connection_config, when use_server_proxy is enabled and an api_key is configured, also pass the key as the OPEN-SANDBOX-API-KEY header via ConnectionConfig.headers — the SDK merges those headers into every execd client, so proxied pings/execs authenticate.

Scoped deliberately:

  • Proxy mode only. In direct-endpoint mode the request terminates at the sandbox itself, which runs untrusted code and must never see the key.
  • Harmless on servers that don't enforce proxy auth (verified: the header is accepted either way).

Testing

Unit: extended test_connection_config_and_image_policy — proxy mode + api_key → headers={"OPEN-SANDBOX-API-KEY": ...} present; direct mode → no headers injected.

End-to-end A/B against a live enforcing deployment (provider → SDK 0.1.15 → server proxy), same script, only the provider tree differing:

Arm Result
provider without this change SandboxReadyTimeoutException — health check false continuously (keyless pings 401), create fails after every retry
provider with this change create ready in 19s, exec("echo e2e-ok") → rc=0 stdout='e2e-ok', clean close

🤖 Generated with Claude Code

The SDK's execd-facing clients (health ping, commands, files) attach only
ConnectionConfig.headers; the api_key field is used by the lifecycle API
clients alone. On servers that enforce API-key auth on /proxy/* routes,
every health ping during Sandbox.create therefore returns 401
(MISSING_API_KEY) even though the key is configured, and creation spins
until ready_timeout before failing. Exec and file operations through the
proxy fail the same way.

Inject the key into ConnectionConfig.headers in server-proxy mode so all
proxied execd requests authenticate. Direct-endpoint mode deliberately
stays keyless: the sandbox endpoint runs untrusted code and must never
see the key. Harmless on servers that do not enforce proxy auth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Hemil Desai <hemild@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@hemildesai
hemildesai marked this pull request as ready for review August 10, 2026 22:31
@hemildesai

Copy link
Copy Markdown
Contributor Author

/claude review

@hemildesai
hemildesai merged commit 649abd2 into main Aug 10, 2026
19 checks passed
@claude

claude Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

SHIP — LGTM, no reliability concerns.

The fix is correct and minimal: injecting OPEN-SANDBOX-API-KEY into ConnectionConfig.headers only when use_server_proxy is set (provider.py:649-650) makes the key reach the SDK's execd-facing clients (health ping/commands/files), which otherwise send only headers and never the api_key field — the documented cause of proxied /proxy/* 401s and create timeouts at ready_timeout. The api_key is not None guard is preserved, and the key is correctly withheld in direct-endpoint mode where untrusted code executes. Test covers both the proxy (header present) and direct (header absent) branches. No async, verifier-correctness, or public-API impact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants