INTEGRITY Dokumentace

Sandbox bridge

Sandbox bridge je referenční implementace Cloudflare Workeru, která zpřístupňuje Sandbox SDK jako HTTP API. Libovolný klient HTTP, ať už jde o skript v Pythonu, službu v Node.js nebo CI pipeline, může vytvářet sandboxy a řídit je bez nutnosti psát Worker. Worker nasadíte v váš účtu, nejde o sdílené API hostované Cloudflare.

Proč používat bridge

Sandbox SDK je určeno k použití v rámci Cloudflare Workers. Pokud vaše aplikace běží mimo ekosystém Workers, nemůže se sandboxy komunikovat přímo.

Bridge zpřístupňuje Sandbox SDK jako standardní HTTP API, takže sandboxy můžete vytvářet a ovládat z libovolného jazyka nebo platformy.

Klíč Metody Sandbox SDK se mapují na jednotlivé HTTP endpointy. Bridge přidává autentizaci, validaci vstupu, omezení cesty pracovního prostoru a volitelný zahřátý fond pro okamžité spuštění kontejneru.

Nasadit

Nasaďte propojovací Worker do svého účtu Cloudflare:

Deploy to Cloudflare

Tlačítko nasadí Worker a vygeneruje SANDBOX_API_KEY secret pro ověřování. Po dokončení nasazení si poznamenejte URL adresu svého Workeru a API klíč, protože je používá každý příklad na této stránce.

Ruční nasazení

Pokud dáváte přednost nasazení po krocích, vytvořte projekt pomocí scaffoldingu a nasaďte jej ručně.

Požadavky:

Kroky:

  1. Vytvořte základní strukturu projektu bridge:

    npm create cloudflare -- sandbox-bridge --template=cloudflare/sandbox-sdk/bridge/worker
    cd sandbox-bridge
  2. Ověřte se u Cloudflare:

    npx wrangler login
  3. Nastavte tajný klíč API. Zvolte libovolnou silnou hodnotu tokenu, klienti ji musí posílat jako Bearer token:

    openssl rand -hex 32 | tee /dev/stderr | npx wrangler secret put SANDBOX_API_KEY

    Klíč se vypíše do vašeho terminálu a rourou odešle do Wrangleru. Uložte si ho, budete ho potřebovat k autentizaci požadavků API.

  4. Nasaďte Worker:

    npx wrangler deploy
  5. Ověřte nasazení:

    curl https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev/health

    Měli byste vidět {"ok":true}.

Image kontejneru

Bridge Dockerfile rozšiřuje cloudflare/sandbox ↗ základní image a předinstaluje běžné nástroje pro agenty:

Přizpůsobte Dockerfile pro přidání jazyků, systémových balíčků nebo nástrojů, které vaše úlohy potřebují.

Použití

Všechny příklady předpokládají, že jsou nastaveny následující proměnné prostředí:

export SANDBOX_API_URL=https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev
export SANDBOX_API_KEY=<your-token>

Vytvoření sandboxu a spuštění příkazu

# Create a sandbox
SANDBOX_ID=$(curl -s -X POST "$SANDBOX_API_URL/v1/sandbox" \
  -H "Authorization: Bearer $SANDBOX_API_KEY" | jq -r '.id')

echo "Sandbox ID: $SANDBOX_ID"

# Run a command
curl -s -X POST "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/exec" \
  -H "Authorization: Bearer $SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"argv": ["sh", "-lc", "echo hello from the sandbox"], "timeout_ms": 10000}'

# Destroy the sandbox when done
curl -s -X DELETE "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID" \
  -H "Authorization: Bearer $SANDBOX_API_KEY"
const API_URL = process.env.SANDBOX_API_URL;
const API_KEY = process.env.SANDBOX_API_KEY;

const headers = {
  Authorization: `Bearer ${API_KEY}`,
  "Content-Type": "application/json",
};

// Create a sandbox
const { id } = await fetch(`${API_URL}/v1/sandbox`, {
  method: "POST",
  headers,
}).then((r) => r.json());

console.log(`Sandbox ID: ${id}`);

// Run a command
// Response is a text/event-stream with the following SSE events:
//   event: stdout  — data is a base64-encoded output chunk
//   event: stderr  — data is a base64-encoded error chunk
//   event: exit    — data is JSON: {"exit_code": 0}
//   event: error   — data is JSON: {"error": "...", "code": "..."}
const execRes = await fetch(`${API_URL}/v1/sandbox/${id}/exec`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    argv: ["sh", "-lc", "echo hello from the sandbox"],
    timeout_ms: 10000,
  }),
});

console.log(await execRes.text());

// Destroy the sandbox when done
await fetch(`${API_URL}/v1/sandbox/${id}`, {
  method: "DELETE",
  headers,
});
# /// script
# dependencies = ["httpx"]
# ///
import os
import httpx

API_URL = os.environ["SANDBOX_API_URL"]
API_KEY = os.environ["SANDBOX_API_KEY"]

headers = {"Authorization": f"Bearer {API_KEY}"}

# Create a sandbox
resp = httpx.post(f"{API_URL}/v1/sandbox", headers=headers)
sandbox_id = resp.json()["id"]
print(f"Sandbox ID: {sandbox_id}")

# Run a command
# Response is a text/event-stream with the following SSE events:
#   event: stdout  — data is a base64-encoded output chunk
#   event: stderr  — data is a base64-encoded error chunk
#   event: exit    — data is JSON: {"exit_code": 0}
#   event: error   — data is JSON: {"error": "...", "code": "..."}
exec_resp = httpx.post(
    f"{API_URL}/v1/sandbox/{sandbox_id}/exec",
    headers=headers,
    json={
        "argv": ["sh", "-lc", "echo hello from the sandbox"],
        "timeout_ms": 10000,
    },
)
print(exec_resp.text)

# Destroy the sandbox when done
httpx.delete(f"{API_URL}/v1/sandbox/{sandbox_id}", headers=headers)

Zápis a čtení souborů

# Write a file
curl -s -X PUT "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/file/workspace/hello.py" \
  -H "Authorization: Bearer $SANDBOX_API_KEY" \
  --data-binary 'print("hello world")'

# Read a file
curl -s "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/file/workspace/hello.py" \
  -H "Authorization: Bearer $SANDBOX_API_KEY"
// Write a file
await fetch(`${API_URL}/v1/sandbox/${id}/file/workspace/hello.py`, {
  method: "PUT",
  headers,
  body: 'print("hello world")',
});

// Read a file
const content = await fetch(
  `${API_URL}/v1/sandbox/${id}/file/workspace/hello.py`,
  { headers },
).then((r) => r.text());

console.log(content);
# /// script
# dependencies = ["httpx"]
# ///
import os
import httpx

API_URL = os.environ["SANDBOX_API_URL"]
API_KEY = os.environ["SANDBOX_API_KEY"]
SANDBOX_ID = os.environ["SANDBOX_ID"]  # from the "Create a sandbox" step
headers = {"Authorization": f"Bearer {API_KEY}"}

# Write a file
httpx.put(
    f"{API_URL}/v1/sandbox/{SANDBOX_ID}/file/workspace/hello.py",
    headers=headers,
    content=b'print("hello world")',
)

# Read a file
content = httpx.get(
    f"{API_URL}/v1/sandbox/{SANDBOX_ID}/file/workspace/hello.py",
    headers=headers,
).text
print(content)

Udržujte bridge aktuální

Většina logiky bridge se nachází v @cloudflare/sandbox balíček. Chcete-li získat nejnovější vylepšení:

  1. Aktualizujte závislost SDK:

    npm update @cloudflare/sandbox
  2. Znovu nasadit:

    npx wrangler deploy

Zkontrolujte vydání sandbox-sdk ↗ na změny v Dockerfile nebo konfiguraci bridge, která může vyžadovat manuální úpravy.

Zdrojový kód a příklady

Zdrojový kód bridge a příklady najdete na GitHubu: