Skip to content

Add Blaxel Sandboxes as a delegated Crabbox provider #285

Description

@coygeek

Feature request: add Blaxel Sandboxes as a delegated Crabbox provider

Summary

Add a first-party blaxel provider for Crabbox so users can run Crabbox workloads inside Blaxel Sandboxes.

This should be a direct CLI provider in Phase 1, implemented as a delegated-run backend. Blaxel Sandboxes do not need to expose a Crabbox-managed SSH target for the initial integration: Blaxel already exposes sandbox lifecycle, filesystem, process execution, logs, ports, preview URLs, labels, regions, memory sizing, and expiration policies through its management and sandbox APIs.

The first PR should make the normal Crabbox flow work:

crabbox warmup --provider blaxel
crabbox run --provider blaxel -- go test ./...
crabbox run --provider blaxel --id blue-lobster --shell 'pnpm install && pnpm test'
crabbox status --provider blaxel --id blue-lobster
crabbox stop --provider blaxel blue-lobster
crabbox cleanup --provider blaxel --dry-run
crabbox doctor --provider blaxel

Why

Blaxel Sandboxes are a strong fit for Crabbox's delegated-run provider model:

  • Blaxel sandboxes are lightweight Linux VM-like runtimes intended for agent code execution.
  • The sandbox API supports process execution with working directories, environment values, stdout/stderr, exit codes, process names, keep-alive, wait-for-completion, and port waiting.
  • The filesystem API supports reading, writing, deleting, tree listing, finding, grepping, binary transfer, and directory operations.
  • The management API supports create/get/list/update/delete for sandboxes, with labels, regions, runtime image, memory, ports, TTL, lifecycle expiration policies, and sandbox endpoint URLs.
  • Blaxel supports automatic standby and expiration policies, which map naturally to Crabbox's retained lease and cleanup story.
  • Preview URLs and /port/{port} access can eventually support a URL bridge or preview workflow, but the first provider does not need to advertise those until end-to-end Crabbox behavior is proven.

This gives Crabbox another hosted sandbox runner alongside providers such as opencomputer, opensandbox, e2b, modal, tensorlake, and upstash-box, while keeping the core provider-neutral.

Recommended Phase 1 scope

Implement provider: blaxel as a Linux-only delegated-run provider.

Provider spec:

Name:        blaxel
Family:      blaxel
Kind:        delegated-run
Targets:     linux
Features:    archive-sync, cleanup
Coordinator: never

Phase 1 should support:

  • crabbox warmup --provider blaxel
  • crabbox run --provider blaxel -- <command>
  • crabbox run --provider blaxel --id <lease-or-slug> -- <command>
  • crabbox run --provider blaxel --sync-only
  • crabbox run --provider blaxel --force-sync-large -- <command>
  • crabbox list --provider blaxel --json
  • crabbox status --provider blaxel --id <lease-or-slug> --json
  • crabbox stop --provider blaxel <lease-or-slug>
  • crabbox cleanup --provider blaxel --dry-run
  • crabbox doctor --provider blaxel

Phase 1 should not advertise or implement:

  • crabbox ssh, unless Blaxel exposes a stable SSH contract that preserves Crabbox's security boundary.
  • VNC, WebVNC, screenshots, desktop, browser, code-server, or Actions runner hydration.
  • Worker/broker coordinator provisioning.
  • Native checkpoint/fork/restore features.
  • URL bridge or preview URL support, unless a first PR proves the full route from Crabbox command to Blaxel preview URL and teardown.
  • Blaxel Agents, Jobs, Models, or MCP Server hosting as primary execution targets. Those can be separate features later; the clean Crabbox fit here is Sandboxes.

Blaxel API fit

The inspected Blaxel docs show the required lifecycle and data-plane primitives.

Management API:

  • POST https://api.blaxel.ai/v0/sandboxes
    • creates a sandbox.
    • accepts metadata.name, metadata.displayName, metadata.labels.
    • accepts spec.region.
    • accepts runtime fields such as image, memory, ports, ttl, expires, and env vars.
    • accepts lifecycle expiration policies such as ttl-idle, ttl-max-age, and date.
  • GET https://api.blaxel.ai/v0/sandboxes/{sandboxName}
    • returns detailed sandbox metadata, including metadata.url, workspace, labels, spec, events, expiresIn, lastUsedAt, and status/events.
  • GET https://api.blaxel.ai/v0/sandboxes
    • lists sandboxes.
    • newer API versions wrap results in {data, meta} with cursor pagination.
    • query support includes showTerminated, cursor, limit, sort, q, and anchor.
  • PUT https://api.blaxel.ai/v0/sandboxes/{sandboxName}
    • updates sandbox configuration and lifecycle policy.
  • DELETE https://api.blaxel.ai/v0/sandboxes/{sandboxName}
    • permanently deletes a sandbox and its data.

Sandbox API:

  • POST {sandbox.metadata.url}/process
    • executes a command.
    • request fields include command, workingDir, env, name, waitForCompletion, timeout, waitForPorts, keepAlive, restartOnFailure, and maxRestarts.
    • response includes status, exit code, stdout, stderr, logs, process name, PID, timestamps, and working directory.
  • GET {sandbox.metadata.url}/process/{identifier}
    • gets process status.
  • GET {sandbox.metadata.url}/process
    • lists processes.
  • GET {sandbox.metadata.url}/process/{identifier}/logs
    • gets process logs.
  • DELETE or stop/kill process endpoints
    • stop or kill process execution when needed.
  • PUT {sandbox.metadata.url}/filesystem/{path}
    • creates or updates files/directories.
  • GET {sandbox.metadata.url}/filesystem/{path}
    • reads file or directory information.
  • GET {sandbox.metadata.url}/filesystem/tree/{path}
    • lists directory tree.
  • DELETE {sandbox.metadata.url}/filesystem/{path}
    • deletes files/directories.
  • POST/GET multipart upload endpoints
    • can support large archive uploads if direct file PUT is not enough.
  • {sandbox.metadata.url}/port/{port}
    • authenticated access to an exposed port.

CLI proof surface:

  • bl version returned 0.1.101 locally.
  • bl --help exposes apply, connect, delete, deploy, get, logs, run, token, and workspaces.
  • bl run sandbox <name> --path /process --data ... runs commands through the sandbox process API.
  • bl get sandboxes -o json returned [] in the current workspace, so no live resources were created during this issue-draft investigation.

The implementation should prefer the REST API or an official Go SDK behind a provider-local client. The bl CLI should be useful for live-smoke diagnostics, but Crabbox should not require a user to have bl installed at runtime if the HTTP API is sufficient.

Authentication and API versioning

Blaxel supports API keys and OAuth tokens. For the Crabbox provider, Phase 1 should support API-key and existing CLI-login-derived token flows without placing secrets on argv.

Suggested environment variables:

CRABBOX_BLAXEL_API_KEY       Preferred Crabbox-specific API key override
BL_API_KEY                   Blaxel SDK/CLI-compatible API key fallback
CRABBOX_BLAXEL_WORKSPACE     Preferred Crabbox-specific workspace override
BL_WORKSPACE                 Blaxel SDK/CLI-compatible workspace fallback
CRABBOX_BLAXEL_API_URL       API base URL override, default https://api.blaxel.ai/v0
CRABBOX_BLAXEL_REGION        Region override
BL_REGION                    Blaxel region fallback
CRABBOX_BLAXEL_IMAGE         Sandbox image, default blaxel/base-image:latest
CRABBOX_BLAXEL_MEMORY_MB     Sandbox memory in MB
CRABBOX_BLAXEL_TTL           Sandbox max-age TTL, for example 30m or 24h
CRABBOX_BLAXEL_IDLE_TTL      Sandbox idle deletion policy, for example 24h
CRABBOX_BLAXEL_WORKDIR       Remote working directory, default /workspace/crabbox
CRABBOX_BLAXEL_EXEC_TIMEOUT_SECS
CRABBOX_BLAXEL_FORGET_MISSING

Suggested config:

provider: blaxel
target: linux
blaxel:
  workspace: ""
  region: us-pdx-1
  image: blaxel/base-image:latest
  memoryMB: 4096
  workdir: /workspace/crabbox
  ttl: 24h
  idleTTL: 24h
  execTimeoutSecs: 600
  ports:
    - target: 3000
      protocol: HTTP

Security rules:

  • Do not persist API keys in repository config.
  • Do not pass API keys on command lines.
  • Send credentials only in request headers (Authorization: Bearer ... or X-Blaxel-Authorization: Bearer ...).
  • Redact authorization headers, API keys, request bodies containing forwarded env values, and Blaxel proxy secret-injection config from errors and logs.
  • Pin the Blaxel-Version header once the implementation chooses the expected response shape. The docs show 2026-04-16 as the initial stable API version and mention newer 2026-04-28 list pagination behavior. The provider should either pin and test one response shape, or support both the bare-array and {data, meta} list shapes.
  • Repository YAML should not be able to set a dangerous API URL that silently redirects an automatically loaded API key. Match the OpenComputer/OpenSandbox posture: allow CRABBOX_BLAXEL_API_URL or --blaxel-api-url, reject userinfo/query/fragment, require HTTPS except for localhost/loopback development.

Lifecycle

Phase 1 should mirror the existing delegated-run providers:

  1. Validate target=linux, credentials, workspace, API URL, region, image, memory, TTL, workdir, and timeout values.
  2. Create or reuse a Blaxel sandbox with:
    • name derived from crabbox-<repo-slug>-<random> or the lease id;
    • metadata.labels carrying Crabbox ownership markers;
    • region;
    • runtime image;
    • memory;
    • optional ports;
    • optional runtime envs from safe config only;
    • lifecycle expiration policy for retained resources.
  3. Store a local lease claim with a blx_ or blaxel_ prefix, friendly slug, repo root, workspace, API endpoint scope, sandbox name, ownership marker, region, image, workdir, idle timeout, and expiration.
  4. Wait until the sandbox reports a deployed/ready status and has a usable metadata.url.
  5. For run, archive-sync the local git manifest into the sandbox workdir:
    • use Crabbox's existing portable archive manifest helpers;
    • upload the archive through Blaxel filesystem or multipart APIs;
    • extract it in the sandbox with the process API;
    • support sync.delete with staged replacement rather than destructive partial writes.
  6. Execute the requested command via POST {metadata.url}/process with:
    • workingDir set to the configured workdir;
    • forwarded env in the JSON body, not argv;
    • shell wrapping consistent with existing delegated backends;
    • timeout from Crabbox config;
    • waitForCompletion or process polling/log streaming depending on the reliable API behavior.
  7. Mirror the remote exit code in the Crabbox exit code.
  8. If --keep is not set, delete the sandbox on successful release.
  9. If --keep or --keep-on-failure retains the sandbox, update the local lease activity and print rerun/stop guidance.
  10. list and status should start from local Crabbox lease claims, fetch Blaxel status for each retained sandbox, and return normalized Crabbox views without provider-owned table rendering.
  11. stop should delete only a sandbox whose Blaxel labels and local claim ownership marker both match.
  12. cleanup should honor --dry-run, local idle/TTL state, Blaxel lifecycle status, and full ownership predicates before deleting anything.

Ownership and cleanup safety

Use labels and local claims together. Suggested Blaxel sandbox labels:

crabbox=true
crabbox.provider=blaxel
crabbox.lease=<cbx_... or local lease id>
crabbox.slug=<friendly-slug>
crabbox.claim=<random ownership marker scoped to endpoint/workspace>
crabbox.repo=<repo slug or short hash>

Safety requirements:

  • Do not delete a sandbox based on name prefix alone.
  • Do not reuse or stop a sandbox unless both local claim and remote labels match.
  • Bind the local claim to API URL and workspace so a stale local claim cannot delete a sandbox after the operator switches accounts/workspaces.
  • Treat 404/missing responses as account-ambiguous by default. Preserve the local claim unless --blaxel-forget-missing is explicitly set.
  • Preserve recovery state on ambiguous create/delete failures. If POST /sandboxes times out or returns an ambiguous server/transport error after the sandbox may have been created, keep enough local state to find and delete the matching labeled sandbox later.
  • Never include API keys or forwarded environment values in local claim files, logs, docs examples, or error messages.

Capabilities and honest non-goals

Phase 1 capabilities:

  • SSH: no.
  • Crabbox sync: yes, via archive upload/extract implemented by the delegated backend.
  • Env forwarding: yes, in JSON request bodies, never argv.
  • Cleanup: yes, if ownership predicates and local claims are implemented.
  • Provider doctor: yes, non-mutating.
  • URL bridge / previews: no in Phase 1 unless fully proven.
  • Desktop / browser / code: no.
  • Actions runner hydration: no.
  • Coordinator: no.

Future capabilities after Phase 1:

  • URL bridge or preview URL creation for crabbox ports / preview workflows, using Blaxel preview URLs or authenticated /port/{port}.
  • Volumes for durable cache/workspaces.
  • Blaxel Agent/Job execution modes as separate provider families or command integrations.
  • OAuth/service-account auth beyond API key and CLI-derived token support.
  • Native run proof/session support if Blaxel process logs can provide bounded streaming/timing metadata that matches Crabbox's proof contract.

Implementation outline

Likely files to add or modify:

File Change
internal/providers/blaxel/provider.go Register blaxel, define spec, flags, config validation, Configure, ConfigureDoctor.
internal/providers/blaxel/backend.go Implement delegated Warmup, Run, List, Status, Stop, Cleanup, and Doctor.
internal/providers/blaxel/client.go Implement Blaxel REST client or wrap official Go SDK behind a fakeable provider-local interface.
internal/providers/blaxel/sync.go Archive upload/extract helpers if the backend needs Blaxel-specific filesystem/multipart handling.
internal/providers/blaxel/flags.go Provider flags and env-safe application into cli.Config.
internal/providers/blaxel/provider_test.go Provider spec, aliases, flags, config validation, target/feature coverage.
internal/providers/blaxel/client_test.go HTTP request/response fixtures, auth header redaction, version header, pagination/list shape, process/filesystem payloads.
internal/providers/blaxel/backend_test.go Fake API lifecycle tests for warmup/run/list/status/stop/cleanup, ownership safety, ambiguous create/delete recovery.
internal/providers/all/all.go Blank-import internal/providers/blaxel.
internal/providers/all/all_test.go Add built-in provider registration/doctor coverage.
internal/cli/config.go Add typed BlaxelConfig, file config, env overrides, defaults, and config-show redaction.
internal/cli/config_test.go Config file/env/default/redaction tests.
internal/cli/providers_builtin_test.go Add blaxel to built-in provider discovery and feature expectations.
docs/providers/blaxel.md Provider runbook with auth, config, lifecycle, gotchas, and live smoke.
docs/providers/README.md Add Blaxel to delegated provider table.
docs/features/providers.md Add Blaxel to delegated-run provider list.
docs/provider-backends.md Add Blaxel to the built-in delegated provider catalog.
docs/source-map.md Add Blaxel provider source mapping.
scripts/live-blaxel-smoke.sh Optional opt-in live smoke.
scripts/live-blaxel-smoke.test.js Test smoke-script classifications without live Blaxel calls.

Tests

Implementation should include:

  • Provider registration tests:
    • canonical blaxel resolves through provider lookup;
    • aliases, if any, are intentional and tested;
    • spec is delegated-run, Linux-only, direct-only, and advertises only implemented features.
  • Config tests:
    • blaxel: YAML fields load correctly;
    • env overrides work;
    • repository YAML cannot set unsafe API URL if the implementation follows the OpenComputer/OpenSandbox trust boundary;
    • config show redacts API keys and secret-bearing runtime envs.
  • Client tests:
    • Authorization or X-Blaxel-Authorization is sent, but never printed;
    • X-Blaxel-Workspace or equivalent workspace routing is sent if required by the API;
    • Blaxel-Version is pinned or response-shape fallback is tested;
    • create payload includes metadata labels, region, runtime image, memory, ports, TTL/lifecycle policy;
    • list supports {data, meta} pagination and older bare-array response if unpinned;
    • get/delete sandbox endpoints are correct;
    • filesystem upload and process-exec payloads are correct;
    • API errors redact bearer tokens and request bodies containing env values.
  • Backend tests:
    • Warmup creates and claims a sandbox;
    • Run creates/reuses, archive-syncs, executes, streams/buffers output, mirrors exit code, and stops when Keep=false;
    • --sync-only syncs and stops without running the user command;
    • --no-sync still ensures the workdir exists;
    • delegated sync guardrails reject unsupported options while allowing --force-sync-large and --sync-only;
    • env forwarding is sent in request bodies, not argv;
    • list/status return normalized Crabbox views;
    • stop/cleanup refuse foreign or partially labeled resources;
    • missing/inaccessible resources preserve claims unless forget-missing is explicit;
    • ambiguous create/delete behavior preserves recovery state.
  • Docs/script tests:
    • docs links/check-command-docs still pass;
    • live smoke script classifies environment_blocked, quota_blocked, validation_failed, and live_blaxel_smoke_passed distinctly.

Acceptance criteria

  • crabbox providers lists blaxel as a Linux delegated-run provider.
  • crabbox doctor --provider blaxel performs only non-mutating checks:
    • credentials/workspace are present;
    • API URL is safe;
    • management API is reachable;
    • sandbox list can be queried;
    • region/image defaults are reported;
    • Crabbox-owned inventory count is reported.
  • Missing credentials fail fast with an actionable error naming the required env vars without printing secret values.
  • crabbox warmup --provider blaxel creates or reuses a Blaxel sandbox, writes a local claim, and prints the normal Crabbox lease summary.
  • crabbox run --provider blaxel -- echo ok syncs the repo archive into the configured workdir, executes the command through the Blaxel process API, prints stdout/stderr, and returns the remote exit code.
  • crabbox run --provider blaxel --id <slug-or-lease> -- echo ok reuses only a locally claimed, ownership-verified sandbox.
  • crabbox list/status --provider blaxel --json returns normalized Crabbox views.
  • crabbox stop --provider blaxel <slug-or-lease> deletes only an owned sandbox and removes the local claim after success or known-safe absence.
  • crabbox cleanup --provider blaxel --dry-run reports only owned resources and performs no mutation.
  • crabbox cleanup --provider blaxel deletes only resources whose local claim and Blaxel labels prove Crabbox ownership.
  • --keep and --keep-on-failure retain sandboxes with clear rerun and stop guidance.
  • --checksum, SSH-only options, VNC/desktop/code/actions-runner paths, and unsupported artifact/download flags are rejected honestly through the delegated provider guardrails.
  • Unit tests do not require live Blaxel credentials.
  • Docs explain auth, workspace/region/image/memory/workdir/TTL config, delegated-run limitations, cleanup safety, and live-smoke prerequisites.

Verification commands for the implementation PR

go test ./internal/providers/blaxel ./internal/providers/all ./internal/cli ./cmd/crabbox
go test -race ./internal/providers/blaxel ./internal/providers/all ./internal/cli
go vet ./...
node --test scripts/live-blaxel-smoke.test.js
node scripts/check-docs-links.mjs
node scripts/check-command-docs.mjs

Optional live validation:

CRABBOX_LIVE=1 CRABBOX_LIVE_PROVIDERS=blaxel scripts/live-blaxel-smoke.sh

The live smoke should:

  1. require CRABBOX_BLAXEL_API_KEY or BL_API_KEY;
  2. require CRABBOX_BLAXEL_WORKSPACE or BL_WORKSPACE, unless the implementation can resolve workspace safely from an existing CLI login;
  3. create exactly one short-lived Crabbox-owned sandbox;
  4. prove archive sync with a file from the local repo;
  5. prove command execution and nonzero exit propagation;
  6. prove off-argv environment forwarding;
  7. prove list/status;
  8. stop the sandbox;
  9. verify the Crabbox-owned Blaxel inventory is empty afterward;
  10. print one final classification such as live_blaxel_smoke_passed, environment_blocked, quota_blocked, or validation_failed.

Research notes

Inspected local Crabbox sources and docs:

  • crabbox/AGENTS.md
  • crabbox/docs/provider-backends.md
  • crabbox/docs/features/provider-authoring.md
  • crabbox/docs/features/providers.md
  • crabbox/docs/providers/opensandbox.md
  • crabbox/docs/providers/opencomputer.md
  • crabbox/internal/providers/opencomputer
  • crabbox/internal/providers/opensandbox
  • crabbox/internal/providers/all/all.go
  • crabbox/internal/cli/config.go
  • crabbox/internal/cli/provider_backend.go

Inspected local Blaxel docs bundle:

  • docs.blaxel.ai/2026-06-12_docs_blaxel_ai_combined.md
  • https://docs.blaxel.ai/Sandboxes/Overview
  • https://docs.blaxel.ai/Sandboxes/Processes
  • https://docs.blaxel.ai/Sandboxes/Filesystem
  • https://docs.blaxel.ai/Sandboxes/Ports
  • https://docs.blaxel.ai/Sandboxes/Preview-url
  • https://docs.blaxel.ai/Sandboxes/Expiration
  • https://docs.blaxel.ai/Sandboxes/Variables-and-secrets
  • https://docs.blaxel.ai/Security/Access-tokens
  • https://docs.blaxel.ai/api-reference/introduction
  • https://docs.blaxel.ai/api-reference/compute/create-sandbox
  • https://docs.blaxel.ai/api-reference/compute/get-sandbox
  • https://docs.blaxel.ai/api-reference/compute/list-sandboxes
  • https://docs.blaxel.ai/api-reference/compute/delete-sandbox
  • https://docs.blaxel.ai/api-reference/process/execute-a-command
  • https://docs.blaxel.ai/cli-reference/commands/bl_run
  • https://docs.blaxel.ai/cli-reference/commands/bl_connect_sandbox
  • https://docs.blaxel.ai/cli-reference/commands/bl_get_sandboxes
  • https://docs.blaxel.ai/cli-reference/commands/bl_delete_sandbox
  • https://docs.blaxel.ai/cli-reference/commands/bl_logs
  • https://docs.blaxel.ai/cli-reference/commands/bl_token

Local CLI checks:

  • bl --help
  • bl --version
  • bl run --help
  • bl get sandboxes --help
  • bl delete sandbox --help
  • bl connect sandbox --help
  • bl logs --help
  • bl token --help
  • bl get sandboxes -o json

Open questions

  • Should the provider use the official Blaxel Go SDK if it is stable enough, or a small provider-local REST client like OpenComputer?
  • Which Blaxel-Version should be pinned for first implementation: earliest stable 2026-04-16, newer list-pagination behavior around 2026-04-28, or the current latest stable supported by the service?
  • Should Phase 1 create sandboxes with ttl, ttl-idle, or both? Crabbox should probably keep local idle cleanup as the primary safety model and set a provider-side max-age/idle policy as a backstop.
  • What should the default region be? The examples use us-pdx-1, but the provider may be better off requiring CRABBOX_BLAXEL_REGION/BL_REGION until a live region listing/default is verified.
  • Should Phase 1 expose configured sandbox ports, or should ports/preview URLs wait for a separate URL-bridge PR?
  • Does Blaxel's sandbox API support efficient large archive upload/extract for real Crabbox repositories through multipart upload, or should the first implementation use a process-based bootstrap helper after uploading an archive file?

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low-risk cleanup, docs, polish, ergonomics, or speculative feature.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:auth-providerThis issue is about auth, provider routing, model choice, or SecretRef resolution.issue-rating: 🌊 off-meta tidepoolIssue quality rating does not apply to this item.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions