Skip to content

feat: replace Docker widget sandboxing with Secure Exec (V8 isolates)#47

Merged
homanp merged 9 commits intomainfrom
cursor/secureexec-dev-widget-integration-ef42
Mar 19, 2026
Merged

feat: replace Docker widget sandboxing with Secure Exec (V8 isolates)#47
homanp merged 9 commits intomainfrom
cursor/secureexec-dev-widget-integration-ef42

Conversation

@homanp
Copy link
Copy Markdown
Owner

@homanp homanp commented Mar 19, 2026

What

Replace the Docker-based widget build and serve system with Secure Exec — a V8 isolate-based secure Node.js execution library. Each widget now runs in its own NodeRuntime sandbox instead of a shared Docker container.

Architecture:

  1. Shared base template — On first widget build, a shared base directory is created with all npm deps + shadcn/ui components pre-installed. This is reused across all widget sandboxes.
  2. Per-widget sandbox — Each widget gets a temp directory copied from the base template. The AI agent writes code into it, Vite builds the widget, and a SecureExec NodeRuntime serves the built files via HTTP.
  3. Proxy route — The Next.js API route proxies iframe requests to the sandbox's HTTP server.

Changes:

  • src/lib/widget-runner.ts — Complete rewrite. Each widget sandbox:
    • Copies the shared base template (with all deps + shadcn pre-installed)
    • Agent writes widget code into the sandbox directory
    • vite build runs in the sandbox to produce static assets
    • A SecureExec NodeRuntime serves the built files via an HTTP file server
  • src/app/api/widget/[id]/[[...path]]/route.ts — Updated proxy route to use fetchFromWidget() which fetches from the sandbox's HTTP server
  • src/app/api/chat/route.ts — Updated system prompt to reference Secure Exec instead of Docker
  • next.config.ts — Added secure-exec and @secure-exec/* to serverExternalPackages, removed dockerode
  • package.json — Added secure-exec, removed dockerode and @types/dockerode
  • .github/workflows/ci.yml — Updated Node version from 20 to 22 (required for isolated-vm native prebuilds)
  • AGENTS.md — Updated to reflect new architecture (no Docker required)

Why

Secure Exec provides lightweight, fast V8 isolate-based sandboxing that eliminates the Docker dependency:

  • No infrastructure required — No Docker daemon, no container images, no volume management
  • ~176x faster cold start than container-based sandboxes
  • ~75x less memory per widget instance (~3.4 MB vs ~256 MB container minimum)
  • Full Node.js compatibility — fs, child_process, http, npm all work inside the isolate
  • Deny-by-default permissions — Granular control over filesystem, network, and process access

Test plan

  • Tests pass locally (npm test — 42/42 passing)
  • Lint passes (npm run lint — 0 errors)
  • TypeScript compiles cleanly (npx tsc --noEmit)
  • Production build succeeds (npm run build)
  • Tested manually — created a counter widget end-to-end, verified interactive functionality
Open in Web Open in Cursor 

- Replace dockerode with secure-exec for widget build and serve
- Each widget gets its own NodeRuntime (V8 isolate) with in-memory filesystem
- Widget files are written to virtual filesystem, built with Vite, served via HTTP server inside the isolate
- Proxy route uses runtime.network.fetch() instead of Docker container port forwarding
- Update system prompt to reference Secure Exec instead of Docker
- Remove dockerode and @types/dockerode dependencies
- Update AGENTS.md to reflect new architecture (no Docker required)

Co-authored-by: Ismail Pelaseyed <homanp@users.noreply.github.com>
@github-actions github-actions bot added the contributor:verified Contributor passed trust analysis. label Mar 19, 2026
cursoragent and others added 7 commits March 19, 2026 09:31
….config

Co-authored-by: Ismail Pelaseyed <homanp@users.noreply.github.com>
isolated-vm (transitive dep of secure-exec) ships prebuilts for Node 22
(ABI 137) but its source fails to compile on Node 20 CI runners due to
V8 header incompatibility.

Co-authored-by: Ismail Pelaseyed <homanp@users.noreply.github.com>
…fetch

- Use NodeFileSystem (real host FS) so build tools (npm, vite) work
- Shared base template with npm deps + shadcn components created once
- Each widget sandbox copies base, agent writes into it, vite builds
- SecureExec runtime serves built files via HTTP inside the sandbox
- Use async exec for npm/vite to avoid blocking event loop
- Use host fetch instead of runtime.network.fetch for server healthcheck
  and widget proxying (server binds to host loopback)
- Upgrade secure-exec from placeholder 0.0.1 to 0.1.0
- Fix Turbopack external resolution by removing secure-exec from
  serverExternalPackages (ESM-only, no main field)
- Forward tool-result events to clear stale action labels in chat UI
- Replace DigitalOcean Droplet deploy with Railway in CI workflow
- Remove Docker files (Dockerfile, docker-compose, Caddyfile, .dockerignore,
  docker/widget-base) no longer needed with secure-exec sandboxing
- Clean up Makefile to remove Docker targets

Made-with: Cursor
Return auto-refreshing loading page instead of a hard 404 when the
widget code isn't in the DB yet. The bootstrap POST and sync run
async, so the iframe can load before the DB is populated.

Made-with: Cursor
…tandalone output

- Exclude drizzle.config.ts and data/ from tsconfig (pre-existing type
  errors that fail production builds)
- Remove output: "standalone" from next.config.ts (was needed for Docker,
  incompatible with Railway's npm start)

Made-with: Cursor
Remove Docker from prerequisites, simplify setup instructions,
and update architecture diagram to reflect V8 isolate sandboxing.

Made-with: Cursor
@homanp homanp marked this pull request as ready for review March 19, 2026 18:02
@homanp homanp changed the title Replace Docker widget sandboxing with Secure Exec (V8 isolates) feat: replace Docker widget sandboxing with Secure Exec (V8 isolates) Mar 19, 2026
@homanp homanp merged commit 27d2d36 into main Mar 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:verified Contributor passed trust analysis.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants