Skip to content

fix(sdk): carry API key on execd requests per use_server_proxy declaration - #1687

Open
jiawen7777 wants to merge 1 commit into
opensandbox-group:mainfrom
jiawen7777:fix/sdk-execd-proxy-api-key
Open

fix(sdk): carry API key on execd requests per use_server_proxy declaration#1687
jiawen7777 wants to merge 1 commit into
opensandbox-group:mainfrom
jiawen7777:fix/sdk-execd-proxy-api-key

Conversation

@jiawen7777

Copy link
Copy Markdown
Contributor

Summary

Testing

  • Not run (explain why)
  • Unit tests
  • Integration tests
  • e2e / manual verification

6 new tests in tests/test_execd_proxy_auth_headers.py lock: declared proxy → key attached regardless of endpoint URL shape; direct mode → key never attached; no key configured → header omitted (async + sync). Full SDK suite, ruff check, and pyright all pass.

e2e: verified against a multi-tenant deployment — without the fix connect() fails after 30s with SandboxReadyTimeoutException while the server logs 401 MISSING_API_KEY on the proxy health route; with the fix connect() succeeds in <1s and commands/files work with no workaround.

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

  • Linked Issue or clearly described motivation
  • Added/updated docs (if needed) — behavior now matches documented semantics, no docs change needed
  • Added/updated tests (if needed)
  • Security impact considered — direct mode test-locked to never attach the key
  • Backward compatibility considered — header only added when use_server_proxy=True; single-tenant deployments unaffected (server already exempts proxy paths per fix(server): skip auth for proxy-to-sandbox paths; strict path matching #250)

…ation

Multi-tenant servers authenticate the proxy route too, but execd adapters
sent no API key — Sandbox.connect() surfaced the 401 as a 30s timeout.
Attach the key only when the client declared proxy mode; in direct mode
it must never travel into the untrusted sandbox.

Fixes opensandbox-group#1686
@github-actions github-actions Bot added sdk/python size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 824254411d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +808 to +811
if connection_config.use_server_proxy:
api_key = connection_config.get_api_key()
if api_key:
headers["OPEN-SANDBOX-API-KEY"] = api_key

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Gate execd API keys in the JavaScript SDK

When a JavaScript client supplies an API key while using the default direct mode, ConnectionConfig inserts that key into its shared headers (sdks/sandbox/javascript/src/config/connection.ts:342-346), and DefaultAdapterFactory.createExecdStack() forwards those headers to execd (sdks/sandbox/javascript/src/factory/defaultAdapterFactory.ts:53-62). Thus the new direct-mode security invariant is Python-only: JavaScript still sends the lifecycle credential into the untrusted sandbox. Apply the same useServerProxy gate to JavaScript execd/egress header construction while retaining authentication on lifecycle requests.

AGENTS.md reference: sdks/AGENTS.md:L122-L122

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense and it's the mirror image of the bug fixed here: instead of missing the key in proxy mode, the JS/C# SDKs attach it unconditionally, so in direct mode the credential travels straight into the untrusted sandbox with no server in the path to strip it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've kept this PR scoped to Python (single concern) and opened #1689 to track the JS/C# side — the fix direction is the same declaration-gated injection the Go SDK already implements.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1691 is already addressing it

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

Labels

sdk/python size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-tenant servers: execd-plane requests omit OPEN-SANDBOX-API-KEY when use_server_proxy=True, surfacing as a 30s health-check timeout

1 participant