Skip to content

[Sandbox] Scope pooled sandbox credentials - #4782

Draft
Wauplin wants to merge 1 commit into
mainfrom
security/harden-pool-isolation
Draft

[Sandbox] Scope pooled sandbox credentials#4782
Wauplin wants to merge 1 commit into
mainfrom
security/harden-pool-isolation

Conversation

@Wauplin

@Wauplin Wauplin commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Related to https://huggingface.slack.com/archives/C03Q18WK18T/p1788160539575999, let's see what we want to do first

Summary

  • keep the derived pool-host credential on management requests and use the random capability returned by sandbox-server for every shared sandbox operation
  • recover that scoped capability when Sandbox.connect reconnects to a pooled sandbox
  • stop the internal sandbox transport from following redirects
  • update the fake protocol server and tests to verify unique proxy credentials, scoped exec/delete, reconnect, and refusal of old hosts without scoped-token support
  • correct the concepts and user guides for the credential and symlink-safe file models

Server side: huggingface/sandbox-server#14

Compatibility and rollout

This requires sandbox-server 0.6.0. Publish the server PR first and recycle existing pool hosts before releasing this client. An upgraded client intentionally refuses to create a shared sandbox on an older host that does not return a scoped token. Older clients can keep making ordinary scoped calls to the new server, but pooled proxy calls return 403 until the client is upgraded.

Checked

  • make style
  • make quality
  • pytest tests/test_sandbox.py (44 passed)

Note

High Risk
Changes authentication for pooled sandboxes and requires sandbox-server 0.6.0 with host recycling; misaligned rollout breaks pool create/connect or proxy until clients and hosts are upgraded together.

Overview
Pooled sandboxes no longer reuse the host-wide HMAC token for exec, files, proxy, or kill. The client keeps that credential for host management only; each shared sandbox gets a random capability from POST /v1/sandboxes and sends it on scoped routes via X-Sandbox-Token. Sandbox.connect for host.local ids fetches the capability from GET /v1/sandboxes/<id>/token (management auth). Hosts that omit token in create responses are rejected with a clear upgrade message.

Transport hardening: the internal httpx client sets follow_redirects=False so auth headers from an in-sandbox app cannot be forwarded on redirects; docs warn the same for user HTTP clients using [proxy_headers].

Docs describe the two-tier auth model, per-sandbox proxy token handling, symlink-safe pooled file API, and in-memory per-sandbox env on pool hosts.

Tests extend the fake sbx-server to enforce token routing, cover reconnect, unique proxy tokens per pool create, and redirect behavior.

Reviewed by Cursor Bugbot for commit dce05c5. Bugbot is set up for automated code reviews on this repo. Configure here.

@bot-ci-comment

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit dce05c5. Configure here.

host.live = host.capacity # the host is full; stop reserving it
return None
item = sandboxes[0]
sandbox_token = _scoped_token(item)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Create leaks sandbox without token

Medium Severity

A successful create POST is not rolled back when _scoped_token rejects the response. The host keeps the new sandbox while create releases the reserved slot, so retries can fill the host with sandboxes the client never received.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit dce05c5. Configure here.

@Wauplin
Wauplin marked this pull request as draft August 31, 2026 13:44
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.

1 participant