News

Run Cursor Cloud Agents in Vercel Sandbox: Verify the Isolation Boundary

Test claim ownership, retry deduplication, credential scope, concurrency limits, timeouts, cleanup, and recovery before running Cursor agents in production.

2026-09-07

A dark glass-and-metal machine with three separate cylindrical chambers illuminated by cyan and amber lights.
Three enclosed chambers visualize the separate execution environments that a control plane must provision, monitor, and clean up.

What Vercel published

On September 3, 2026, Vercel announced a reference architecture for running Cursor Cloud Agents in Vercel Sandbox. Cursor keeps the agent harness and inference loop; Cursor Self-Hosted Machines lets an Enterprise customer supply the environment where an agent clones a repository, edits files, runs commands, and executes tests. Vercel Functions and Workflow act as the control plane, while each request receives a dedicated environment from the documented Vercel Sandbox product, described by Vercel as an isolated Firecracker microVM.

That is a useful architecture claim, but it is not your production acceptance result. Deploy the reference project into a disposable Vercel project, connect a non-production Cursor pool, and prove the boundaries you will rely on. The drill below measures orchestration and credential placement. It does not independently certify the microVM implementation, the repository contents, or the safety of an agent's code changes.

Turn the diagram into seven invariants

The Vercel implementation guide separates a durable control plane from request-scoped compute. Its pool can remain registered with zero workers. A controller claims pending requests, starts one child workflow per claim, creates or retrieves a deterministically named Sandbox, starts a worker, monitors agent status, then stops the Sandbox and releases the claim.

Translate that sequence into invariants before testing: one claim has one owning worker ID; one request ID resolves to one child workflow and one Sandbox name; a retry does not start a second worker process; the team service-account key never enters compute; the worker token belongs to the requesting user and is delivered through a restricted file; admission per discovery tick is capped; and every terminal or failed path stops compute and releases the claim. This is narrower than the general coordination problem covered in running AI agents in parallel: here, every assertion is tied to a concrete Cursor request.

Prepare an evidence ledger before the first request

Use a repository containing only a harmless task, such as changing one fixture string and running one deterministic unit test. Disable deploy credentials and production integrations. Create a unique run label such as accept-20260907-a, then propagate it through controller logs without putting it into a secret value. Record timestamps in UTC and retain the Vercel Workflow run URLs, Cursor request IDs, worker IDs, Sandbox names, status transitions, process-start count, stop result, and claim-release result.

InvariantEvidence to retainPass condition
Claim ownershipRequest ID, claim responses, owning worker IDExactly one controller wins; losers do not dispatch
Retry deduplicationChild workflow ID, Sandbox name, worker process countRepeated step resolves to the same resources
Credential boundaryRedacted environment keys, file metadata, process argumentsNo service key in compute; no worker token value in logs or arguments
Admission capPending count and claimed count for one tickObserved claims do not exceed the configured per-tick cap
LifecycleStatus timeline, Sandbox stop, claim lookupIdle, timeout, and failure paths leave neither live compute nor a live claim

Do not capture the credentials themselves. Record a key name, location, file mode, hash prefix only if your security policy permits it, and whether the value appeared in process arguments or logs. The goal is to prove placement without creating a second leak in your test evidence. Keep these controls aligned with the broader zero-trust architecture for AI agents.

Race two claimers, then replay one worker step

Create one pending Cursor request and pause both controller instances immediately before the claim call. Release them together. Vercel's guide says Cursor's claim endpoint atomically assigns one pending request to one worker ID, and explicitly limits that guarantee to request assignment. Pass only if one call owns the claim, one child workflow is dispatched, and the losing path produces no Sandbox. A single successful response without a competing attempt does not test the race.

Next, pause the winning child after provisioning and replay its provision/start step with the same request ID. The reference design derives deterministic worker and Sandbox names, uses Sandbox.getOrCreate, protects the process with non-blocking flock, and uses Workflow hook leases. Pass if both attempts point to one Sandbox and there is one worker process. Fail if you observe two names, two processes, or a retry whose ownership cannot be connected to the original claim. Atomic claim plus deterministic naming is still not a blanket exactly-once guarantee; test the external effects your deployment actually performs.

Inspect credentials from both sides of the boundary

In the documented design, the Cursor service-account API key remains in Functions and Workflow. The control plane mints a one-hour token scoped to the requesting user, writes it to /tmp/cursor-worker-token with mode 0600, and starts the CLI with --auth-token-file rather than placing the token in process arguments. Inspect the Sandbox environment-key list, the token file's owner and mode, the worker command line, and redacted logs.

Pass if the service-account key is absent from the Sandbox, the token is not printed or present in the process arguments, the file is readable only by its intended user, and request B receives a different token placement event from request A. Do not claim cryptographic isolation from these observations. They verify how your deployed integration transports credentials. Test authorization separately by giving the disposable user access only to the fixture repository and confirming an out-of-scope repository operation is denied.

Measure the cap and both clocks

The reference sample sets MAX_WORKERS_PER_TICK to 5. Queue at least 7 harmless requests before a controlled discovery tick, then freeze subsequent polling long enough to count claims. Pass the per-tick check if no more than 5 are claimed in that tick. Call it a per-tick admission cap, not a global concurrency limit: child workers may remain active while later ticks admit more work. If your risk limit is five simultaneous Sandboxes, add an explicit active-worker semaphore and test that separate invariant.

The same sample gives the worker a 600-second idle-release grace period and the Sandbox a 45-minute upper-bound timeout. Its child workflow checks status every 30 seconds for up to 90 checks. Run a short task to the idle path and a deliberately blocked task to the hard-stop path. Record configured values, the last active event, observed stop time, polling granularity, and release completion. Scheduler and polling delay mean elapsed observations need tolerances agreed in advance; do not require an exact second unless the source promises one.

Force failure before declaring cleanup reliable

Run three cleanup cases: normal completion, a forced exception after Sandbox creation, and a missing-Sandbox case. Vercel's sample places cleanup in finally, stops the named Sandbox, tolerates a Sandbox 404, and releases the Cursor claim even after the stop attempt. Its release helper also treats an already absent claim as complete. For each case, query both resources after the workflow finishes. A successful workflow status alone is insufficient.

Pass only if normal and forced-failure cases leave no running Sandbox and no live claim, while repeating cleanup is harmless. Then submit a fresh request for the same pool and confirm it can be claimed and run. This recovery request distinguishes cleanup that merely hides an error from cleanup that restores capacity. Keep an operator action for stopping the controller, stopping named Sandboxes, releasing claims, and rotating the service key beside your rollback and approval gates.

Use a bounded production gate

Approve the architecture only for the exact snapshot, controller revision, pool configuration, repository scope, and timeout values exercised. Your signed record should contain the seven invariants, each observed result, evidence links, deviations, reviewer, and expiration date. Re-run the drill after changing the snapshot, naming function, claim logic, token delivery, concurrency control, or cleanup path.

A clean pass means the deployed reference behaved as expected under these bounded tests. It does not mean every retry is harmless, every repository is safe, or every future vendor version preserves the same boundary. The most useful result may be a precise failure: a duplicated process, an exposed key name with unexpected value placement, a sixth claim in one tick, or a claim that survives compute.

Sources checked 2026-09-07