Documentation/docs/sandbox/services

#Sandbox Services

Sandbox Services expose named ports inside a sandbox. Use them when a sandbox needs public HTTP routes with method filtering, auth, CORS, rate limits, upstream timeout, path rewrite, and route-level resume behavior.

Services are also the source model for Sandbox0 Functions. A publishable service is public and has a restartable runtime.

Service Model#

FieldTypeDescription
idstringStable service ID. Must be unique in the sandbox
display_namestringOptional human-readable label
portintegerSandbox port to proxy to
runtimeobjectOptional restartable runtime for functions
ingressobjectPublic exposure and route policy
health_checkobjectOptional readiness path

Runtime#

Service runtime supports cmd, warm_process, and manual. Use cmd when Function Gateway should create a new command context for a restored function runtime. Use warm_process when the template already starts a long-lived process and the service should bind to that existing context. For Functions, warm_process_name must reference a cmd warm process alias or context ID; REPL warm processes are not valid HTTP service runtimes.

Ingress#

FieldTypeDescription
publicbooleanExposes the service on the deployment exposure domain
routesarrayOrdered public HTTP routes for this service

When public is true and routes is empty, Sandbox0 creates a default route using the service ID and /.

Route#

FieldTypeDescription
idstringStable route ID. Must be unique within the service
path_prefixstringRequest path prefix to match. Defaults to /
methodsstring arrayAllowed HTTP methods. Empty allows every method
rewrite_prefixstring or nullOptional path prefix replacement before proxying
authobjectOptional request authentication
corsobjectOptional CORS policy
rate_limitobjectOptional per-route rate limit
timeout_secondsintegerOptional upstream timeout in seconds
resumebooleanWhether this route may resume a paused sandbox when auto_resume is enabled

Route rate limits use the gateway rate limit backend. Self-hosted deployments default to process-local memory for simple onboarding. Configure Sandbox0Infra.spec.redis when multiple gateway replicas need shared Redis-backed limits.

Auth#

FieldTypeDescription
modestringnone, bearer, or header
bearer_token_sha256stringSHA-256 hex digest for bearer token auth
header_namestringHeader name for header auth
header_value_sha256stringSHA-256 hex digest for header value auth

Route auth stores SHA-256 digests, not plaintext tokens. Hash secret values before sending service configuration.

List Services#

GET

/api/v1/sandboxes/{id}/services

The response includes publishable, publish_blockers, and exposure_domain.

go
resp, err := sandbox.GetServices(ctx) if err != nil { log.Fatal(err) } fmt.Printf("services: %d\n", len(resp.Services)) for _, service := range resp.Services { fmt.Printf("%s -> port %d\n", service.ID, service.Port) }

Replace Services#

PUT

/api/v1/sandboxes/{id}/services

The update replaces the full service list. Include every service that should remain active.

go
tokenHash := sha256.Sum256([]byte(os.Getenv("PUBLIC_API_TOKEN"))) resp, err := sandbox.UpdateServices(ctx, []apispec.SandboxAppService{ { ID: "api", Port: 8080, Ingress: apispec.SandboxAppServiceIngress{ Public: true, Routes: []apispec.SandboxAppServiceRoute{ { ID: "api", PathPrefix: apispec.NewOptString("/api"), Methods: []string{"GET", "POST"}, Auth: apispec.NewOptSandboxAppServiceRouteAuth(apispec.SandboxAppServiceRouteAuth{ Mode: apispec.SandboxAppServiceRouteAuthModeBearer, BearerTokenSHA256: apispec.NewOptString(hex.EncodeToString(tokenHash[:])), }), RateLimit: apispec.NewOptSandboxAppServiceRouteRateLimit(apispec.SandboxAppServiceRouteRateLimit{ Rps: 20, Burst: 40, }), TimeoutSeconds: apispec.NewOptInt32(30), Resume: true, }, }, }, }, }) if err != nil { log.Fatal(err) } fmt.Printf("services: %d\n", len(resp.Services))

Set Services At Claim Time#

You can attach services when claiming a sandbox. This is useful when the sandbox starts a known HTTP service during boot.

go
sandbox, err := client.ClaimSandbox(ctx, "default", sandbox0.WithSandboxAutoResume(true), sandbox0.WithSandboxServices([]apispec.SandboxAppService{ { ID: "web", Port: 3000, Ingress: apispec.SandboxAppServiceIngress{ Public: true, Routes: []apispec.SandboxAppServiceRoute{ { ID: "web", PathPrefix: apispec.NewOptString("/"), Resume: true, }, }, }, }, }), ) if err != nil { log.Fatal(err) }

Clear Services#

Clearing services removes public HTTP exposure from the sandbox.

go
_, err := sandbox.ClearServices(ctx) if err != nil { log.Fatal(err) }

Behavior Notes#

  • Public HTTP traffic must match a route on a public service.
  • If methods is empty, every HTTP method is allowed for that route.
  • resume is evaluated with sandbox auto_resume. A route with resume: false will not resume a paused sandbox.
  • Public URLs are derived from the deployment exposure domain as {sandbox_id}--p{port}.{exposure_domain}.

Next Steps#

Webhooks

Receive signed sandbox lifecycle, service, and file-related events.

Overview

Package sandbox services into versioned callable functions and manage runtime revisions.