opensandbox-group--opensandbox
e0e362d700
SDK Tests / changes (push) Successful in 2m29s
Real E2E Tests / changes (push) Successful in 2m29s
Deploy Docs Pages / build (push) Has been cancelled
Deploy Docs Pages / deploy (push) Has been cancelled
Real E2E Tests / JavaScript E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Python E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Java E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / C# E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Go E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Real E2E CI (push) Has been cancelled
SDK Tests / SDK CI (push) Has been cancelled
SDK Tests / CLI Tests (push) Has been cancelled
SDK Tests / Python SDK Quality (code-interpreter) (push) Has been cancelled
SDK Tests / Python SDK Quality (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (sandbox) (push) Has been cancelled
SDK Tests / CLI Quality (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Go SDK Quality And Tests (push) Has been cancelled
1636 行
58 KiB
YAML
1636 行
58 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: OpenSandbox Lifecycle API
|
|
version: 0.1.0
|
|
description: |
|
|
The Sandbox Lifecycle API coordinates how untrusted workloads are created,
|
|
executed, paused, resumed, and finally disposed. This specification focuses on
|
|
the primary lifecycle flows for the `sandbox` domain concept. Sandboxes can
|
|
be provisioned directly from container images or restored from snapshots.
|
|
|
|
## Sandbox Lifecycle
|
|
|
|
A sandbox follows this lifecycle:
|
|
|
|
1. **Creation** → Sandbox is provisioned and enters `Running` state
|
|
2. **Execution** → Sandbox is running and ready to accept requests
|
|
3. **Pause** (optional) → `Pausing` → `Paused` (asynchronous process)
|
|
4. **Resume** (optional) → `Resuming` → `Running` (asynchronous process)
|
|
5. **Termination** → `Stopping` → `Terminated` (can be triggered by kill action, TTL expiry, or error)
|
|
6. **Error** → Any state can transition to `Failed` on critical errors
|
|
|
|
The `status` field provides fine-grained details through `state`, `reason`, and `message`.
|
|
|
|
## Authentication
|
|
|
|
API Key authentication is required for all operations:
|
|
|
|
1. **HTTP Header**
|
|
```
|
|
OPEN-SANDBOX-API-KEY: your-api-key
|
|
```
|
|
|
|
2. **Environment Variable** (for SDK clients)
|
|
```
|
|
OPEN_SANDBOX_API_KEY=your-api-key
|
|
```
|
|
|
|
SDK clients will automatically pick up this environment variable.
|
|
servers:
|
|
- url: http://localhost:8080/v1
|
|
description: Local development
|
|
security:
|
|
- apiKeyAuth: []
|
|
tags:
|
|
- name: Sandboxes
|
|
description: Provision and transition sandboxes through their lifecycle
|
|
- name: Snapshots
|
|
description: Create, list, and delete persistent sandbox snapshots
|
|
paths:
|
|
/sandboxes:
|
|
get:
|
|
tags: [ Sandboxes ]
|
|
summary: List sandboxes
|
|
description: |
|
|
List all sandboxes with optional filtering and pagination using query parameters.
|
|
All filter conditions use AND logic. Multiple `state` parameters use OR logic within states.
|
|
parameters:
|
|
- name: state
|
|
in: query
|
|
description: |
|
|
Filter by lifecycle state. Pass multiple times for OR logic.
|
|
Example: `?state=Running&state=Paused`
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
style: form
|
|
explode: true
|
|
- name: metadata
|
|
in: query
|
|
description: |
|
|
Arbitrary metadata key-value pairs for filtering,keys and values must be url encoded
|
|
Example: To filter by `project=Apollo` and `note=Demo Test`: `?metadata=project%3DApollo%26note%3DDemo%252520Test`
|
|
schema:
|
|
type: string
|
|
style: form
|
|
- name: page
|
|
in: query
|
|
description: Page number for pagination
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 1
|
|
- name: pageSize
|
|
in: query
|
|
description: Number of items per page
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 20
|
|
responses:
|
|
'200':
|
|
description: Paginated collection of sandboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ListSandboxesResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
post:
|
|
tags: [Sandboxes]
|
|
summary: Create a sandbox
|
|
description: |
|
|
Creates a new sandbox from a container image or restores one from a
|
|
persistent sandbox snapshot with optional resource limits, environment
|
|
variables, and metadata.
|
|
|
|
Exactly one startup source must be provided:
|
|
- `image` to provision directly from a container image.
|
|
- `snapshotId` to restore from a previously created snapshot.
|
|
|
|
When `image` is provided, `entrypoint` is required. When `snapshotId` is
|
|
provided, `entrypoint` is optional. If omitted, the server defaults the
|
|
sandbox entrypoint to `["tail", "-f", "/dev/null"]`.
|
|
|
|
## Authentication
|
|
|
|
API Key authentication is required via:
|
|
- `OPEN-SANDBOX-API-KEY: <api-key>` header
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSandboxRequest'
|
|
examples:
|
|
deny-with-allowlist:
|
|
summary: Deny by default with allowed domains
|
|
value:
|
|
image:
|
|
uri: python:3.11
|
|
timeout: 3600
|
|
resourceLimits:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
entrypoint: ["python", "/app/main.py"]
|
|
networkPolicy:
|
|
defaultAction: deny
|
|
egress:
|
|
- action: allow
|
|
target: "pypi.org"
|
|
allow-with-denylist:
|
|
summary: Allow by default with a deny rule
|
|
value:
|
|
image:
|
|
uri: python:3.11
|
|
timeout: 3600
|
|
resourceLimits:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
entrypoint: ["python", "/app/main.py"]
|
|
networkPolicy:
|
|
defaultAction: allow
|
|
egress:
|
|
- action: deny
|
|
target: "bad.example.com"
|
|
manual-cleanup:
|
|
summary: Manual cleanup without automatic expiration
|
|
value:
|
|
image:
|
|
uri: python:3.11
|
|
platform:
|
|
os: linux
|
|
arch: amd64
|
|
resourceLimits:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
entrypoint: ["python", "/app/main.py"]
|
|
secure-access:
|
|
summary: Enable secured access for sandbox endpoints in Kubernetes gateway mode
|
|
value:
|
|
image:
|
|
uri: python:3.11
|
|
timeout: 3600
|
|
resourceLimits:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
entrypoint: ["python", "/app/main.py"]
|
|
secureAccess: true
|
|
restore-snapshot:
|
|
summary: Restore from a snapshot
|
|
value:
|
|
snapshotId: snap_123
|
|
timeout: 3600
|
|
resourceLimits:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
restore-snapshot-with-entrypoint:
|
|
summary: Restore from a snapshot with a custom entrypoint
|
|
value:
|
|
snapshotId: snap_123
|
|
timeout: 3600
|
|
resourceLimits:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
entrypoint: ["python", "/workspace/app.py"]
|
|
responses:
|
|
'202':
|
|
description: |
|
|
Sandbox created and provisioned successfully.
|
|
|
|
The returned sandbox includes:
|
|
- `id`: Unique sandbox identifier
|
|
- `status.state: "Running"` (provisioning completed synchronously)
|
|
- `status.reason` and `status.message` indicating current state
|
|
- `metadata`, `expiresAt`, `createdAt`: Core sandbox information
|
|
|
|
Note: startup source details and `updatedAt` are not included in the create response.
|
|
Use GET /sandboxes/{sandboxId} to retrieve the complete sandbox information.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSandboxResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
Location:
|
|
$ref: '#/components/headers/Location'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/snapshots:
|
|
get:
|
|
tags: [Snapshots]
|
|
summary: List snapshots
|
|
description: |
|
|
List all snapshots with optional filtering and pagination using query parameters.
|
|
Snapshots are persistent captures of sandbox state and may outlive the source sandbox.
|
|
parameters:
|
|
- name: sandboxId
|
|
in: query
|
|
description: Filter snapshots by source sandbox identifier
|
|
schema:
|
|
type: string
|
|
- name: state
|
|
in: query
|
|
description: |
|
|
Filter by snapshot lifecycle state. Pass multiple times for OR logic.
|
|
Example: `?state=Ready&state=Failed`
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SnapshotState'
|
|
style: form
|
|
explode: true
|
|
- name: page
|
|
in: query
|
|
description: Page number for pagination
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 1
|
|
- name: pageSize
|
|
in: query
|
|
description: Number of items per page
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 20
|
|
responses:
|
|
'200':
|
|
description: Paginated collection of snapshots
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ListSnapshotsResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/snapshots/{snapshotId}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/SnapshotId'
|
|
get:
|
|
tags: [Snapshots]
|
|
summary: Fetch a snapshot by id
|
|
description: Returns snapshot state and metadata.
|
|
responses:
|
|
'200':
|
|
description: Snapshot current state and metadata
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
delete:
|
|
tags: [Snapshots]
|
|
summary: Delete a snapshot
|
|
description: |
|
|
Delete a persistent sandbox snapshot by id. Snapshots that are still
|
|
being created cannot be deleted.
|
|
|
|
For Kubernetes-backed snapshots, deletion removes OpenSandbox metadata
|
|
and Kubernetes coordination resources, but does not guarantee removal
|
|
of pushed OCI images from the configured registry. Use registry
|
|
retention or garbage collection policies for image lifecycle cleanup.
|
|
responses:
|
|
'204':
|
|
description: Snapshot successfully deleted
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}:
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
get:
|
|
tags: [Sandboxes]
|
|
summary: Fetch a sandbox by id
|
|
description: |
|
|
Returns the complete sandbox information including:
|
|
- `id`, `status`, `metadata`, `expiresAt`, `createdAt`: Core information
|
|
- `image` or `snapshotId`: Startup source information (not included in create response)
|
|
- `entrypoint`: Entry process specification
|
|
|
|
This is the complete representation of the sandbox resource.
|
|
responses:
|
|
'200':
|
|
description: Sandbox current state and metadata
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Sandbox'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
delete:
|
|
tags: [Sandboxes]
|
|
summary: Delete a sandbox
|
|
description: Delete a sandbox, terminating its execution. The sandbox will transition through Stopping state to Terminated.
|
|
responses:
|
|
'204':
|
|
description: |
|
|
Sandbox successfully deleted.
|
|
|
|
Sandbox has been scheduled for termination and will transition to Stopping state, then Terminated.
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}/metadata:
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
patch:
|
|
tags: [Sandboxes]
|
|
summary: Patch sandbox metadata
|
|
description: |
|
|
Update sandbox metadata using JSON Merge Patch semantics (RFC 7396).
|
|
|
|
**Merge Patch rules:**
|
|
| Request body key/value | Behavior |
|
|
|---|---|
|
|
| `"key": "value"` | Add or replace the key |
|
|
| `"key": null` | Delete the key (silently ignored if key does not exist) |
|
|
| key absent | Keep current value (no change) |
|
|
| Empty `{}` | No-op, returns current metadata |
|
|
|
|
Metadata keys and values must comply with Kubernetes label rules:
|
|
- Keys must be valid DNS label names or prefixed DNS subdomains
|
|
- Keys with the `opensandbox.io/` prefix are reserved and rejected
|
|
- Values must be 63 characters or less, matching `[A-Za-z0-9]([-A-Za-z0-9_.]*[A-Za-z0-9])?`
|
|
|
|
This operation does not restart or recreate the sandbox container/pod.
|
|
|
|
**Concurrency:** This endpoint uses read-modify-write without optimistic
|
|
locking (no `resourceVersion` check). Concurrent PATCH requests may
|
|
interleave and silently drop updates. Use a single writer or coordinate
|
|
out-of-band when concurrent modifications to the same key are expected.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PatchSandboxMetadataRequest'
|
|
examples:
|
|
add-and-replace:
|
|
summary: Add new keys and replace existing values
|
|
value:
|
|
team: "platform"
|
|
version: "2.0"
|
|
delete-key:
|
|
summary: Delete a metadata key
|
|
value:
|
|
deprecated-key: null
|
|
mixed-operations:
|
|
summary: Add, replace, and delete in a single request
|
|
value:
|
|
project: "new-project"
|
|
team: null
|
|
environment: "production"
|
|
empty-body:
|
|
summary: No-op (returns current metadata)
|
|
value: {}
|
|
responses:
|
|
'200':
|
|
description: |
|
|
Metadata patched successfully. Returns the complete sandbox resource
|
|
with updated metadata.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Sandbox'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}/snapshots:
|
|
post:
|
|
tags: [Snapshots]
|
|
summary: Create a snapshot from a sandbox
|
|
description: |
|
|
Create a persistent point-in-time snapshot from the sandbox's current state.
|
|
The source sandbox must be `Running`. The returned snapshot id identifies
|
|
the created artifact. Snapshot creation may temporarily pause the sandbox
|
|
while the runtime captures provider-supported state, then the source
|
|
sandbox continues running.
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
requestBody:
|
|
required: false
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSnapshotRequest'
|
|
examples:
|
|
default:
|
|
summary: Create an unnamed snapshot
|
|
value: {}
|
|
named:
|
|
summary: Create a named snapshot
|
|
value:
|
|
name: checkpoint-before-import
|
|
responses:
|
|
'202':
|
|
description: |
|
|
Snapshot creation accepted.
|
|
|
|
The returned snapshot includes `status.state: "Creating"`.
|
|
Poll GET /snapshots/{snapshotId} to track progress until the snapshot
|
|
transitions to `Ready` or `Failed`.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
Location:
|
|
$ref: '#/components/headers/Location'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}/pause:
|
|
post:
|
|
tags: [Sandboxes]
|
|
summary: Pause execution while retaining state
|
|
description: Pause a running sandbox while preserving its state. Poll GET /sandboxes/{sandboxId} to track state transition through Pausing and eventually Paused.
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
responses:
|
|
'202':
|
|
description: |
|
|
Pause operation accepted.
|
|
|
|
Sandbox will transition to Pausing state and eventually Paused.
|
|
Poll GET /sandboxes/{sandboxId} to track progress.
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}/resume:
|
|
post:
|
|
tags: [Sandboxes]
|
|
summary: Resume a paused sandbox
|
|
description: Resume execution of a paused sandbox. Poll GET /sandboxes/{sandboxId} to track state transition through Resuming and eventually Running.
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
responses:
|
|
'202':
|
|
description: |
|
|
Resume operation accepted.
|
|
|
|
Sandbox will transition from Paused → Resuming → Running.
|
|
Poll GET /sandboxes/{sandboxId} to track progress.
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}/renew-expiration:
|
|
post:
|
|
tags: [Sandboxes]
|
|
summary: Renew sandbox expiration
|
|
description: Renew the absolute expiration time of a sandbox.
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RenewSandboxExpirationRequest'
|
|
responses:
|
|
'200':
|
|
description: |
|
|
Sandbox expiration updated successfully.
|
|
|
|
Returns only the updated expiresAt field.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RenewSandboxExpirationResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
/sandboxes/{sandboxId}/endpoints/{port}:
|
|
get:
|
|
tags: [Sandboxes]
|
|
summary: Get sandbox access endpoint
|
|
description: |
|
|
Get the public access endpoint URL for accessing a service running on a specific port
|
|
within the sandbox. The service must be listening on the specified port inside
|
|
the sandbox for the endpoint to be available.
|
|
parameters:
|
|
- $ref: '#/components/parameters/SandboxId'
|
|
- name: port
|
|
in: path
|
|
required: true
|
|
description: Port number where the service is listening inside the sandbox
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 65535
|
|
- name: use_server_proxy
|
|
in: query
|
|
description: Whether to return a server-proxied URL. Cannot be combined with `expires`.
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
- name: expires
|
|
in: query
|
|
required: false
|
|
description: |
|
|
Optional. When set, the server **issues a signed** access route (OSEP-0011). The value
|
|
is **Linux / Unix epoch seconds** — a decimal `uint64` count of **whole seconds** since
|
|
the Unix epoch (`1970-01-01 00:00:00` UTC, same as POSIX / `time(2)`), not
|
|
milliseconds. Normalized to `expires_b36` for the four-segment route token. Omit to
|
|
get the unsigned/legacy response shape. Cannot be combined with `use_server_proxy=true`.
|
|
schema:
|
|
type: string
|
|
pattern: '^(0|[1-9][0-9]*)$'
|
|
minLength: 1
|
|
maxLength: 20
|
|
responses:
|
|
'200':
|
|
description: |
|
|
Endpoint retrieved successfully.
|
|
|
|
Returns the public URL for accessing the service on the specified port.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Endpoint'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
components:
|
|
securitySchemes:
|
|
apiKeyAuth:
|
|
type: apiKey
|
|
in: header
|
|
name: OPEN-SANDBOX-API-KEY
|
|
description: |
|
|
API Key for authentication. Can be provided via:
|
|
1. HTTP Header: OPEN-SANDBOX-API-KEY: your-api-key
|
|
2. Environment variable: OPEN_SANDBOX_API_KEY (for SDK clients)
|
|
parameters:
|
|
SandboxId:
|
|
name: sandboxId
|
|
in: path
|
|
required: true
|
|
description: Unique sandbox identifier
|
|
schema:
|
|
type: string
|
|
SnapshotId:
|
|
name: snapshotId
|
|
in: path
|
|
required: true
|
|
description: Unique snapshot identifier
|
|
schema:
|
|
type: string
|
|
headers:
|
|
XRequestId:
|
|
description: Unique request identifier for tracing
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
Location:
|
|
description: URI of the newly created or related resource
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
RetryAfter:
|
|
description: Suggested delay in seconds before retrying
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
responses:
|
|
Error:
|
|
description: Error response envelope
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
BadRequest:
|
|
description: The request was invalid or malformed
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
Unauthorized:
|
|
description: Authentication credentials are missing or invalid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
Forbidden:
|
|
description: The authenticated user lacks permission for this operation
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
NotFound:
|
|
description: The requested resource does not exist
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
Conflict:
|
|
description: The operation conflicts with the current state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
InternalServerError:
|
|
description: An unexpected server error occurred
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
headers:
|
|
X-Request-ID:
|
|
$ref: '#/components/headers/XRequestId'
|
|
schemas:
|
|
ListSandboxesResponse:
|
|
type: object
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Sandbox'
|
|
pagination:
|
|
$ref: '#/components/schemas/PaginationInfo'
|
|
required: [items, pagination]
|
|
ListSnapshotsResponse:
|
|
type: object
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
pagination:
|
|
$ref: '#/components/schemas/PaginationInfo'
|
|
required: [items, pagination]
|
|
PaginationInfo:
|
|
type: object
|
|
description: Pagination metadata for list responses
|
|
properties:
|
|
page:
|
|
type: integer
|
|
minimum: 1
|
|
description: Current page number
|
|
pageSize:
|
|
type: integer
|
|
minimum: 1
|
|
description: Number of items per page
|
|
totalItems:
|
|
type: integer
|
|
minimum: 0
|
|
description: Total number of items matching the filter
|
|
totalPages:
|
|
type: integer
|
|
minimum: 0
|
|
description: Total number of pages
|
|
hasNextPage:
|
|
type: boolean
|
|
description: Whether there are more pages after the current one
|
|
required: [page, pageSize, totalItems, totalPages, hasNextPage]
|
|
CreateSandboxResponse:
|
|
type: object
|
|
description: Response from creating a new sandbox. Contains essential information without startup source details and updatedAt.
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique sandbox identifier
|
|
|
|
status:
|
|
$ref: '#/components/schemas/SandboxStatus'
|
|
description: Current lifecycle status and detailed state information
|
|
|
|
metadata:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Custom metadata from creation request
|
|
|
|
extensions:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Opaque extension data restored from provider-specific storage
|
|
|
|
platform:
|
|
$ref: '#/components/schemas/PlatformSpec'
|
|
description: |
|
|
Platform constraint echoed from request or workload template.
|
|
Null when no scheduling constraint is provided.
|
|
|
|
expiresAt:
|
|
type: string
|
|
format: date-time
|
|
description: Timestamp when sandbox will auto-terminate. Omitted when manual cleanup is enabled.
|
|
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
description: Sandbox creation timestamp
|
|
|
|
entrypoint:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: |
|
|
Entry process specification for the sandbox. For image-created sandboxes,
|
|
this is copied from the creation request. For snapshot-created sandboxes,
|
|
this is restored from the snapshot.
|
|
|
|
required:
|
|
- id
|
|
- status
|
|
- createdAt
|
|
- entrypoint
|
|
|
|
CreateSnapshotRequest:
|
|
type: object
|
|
description: Optional settings for creating a sandbox snapshot.
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Optional human-readable snapshot name.
|
|
minLength: 1
|
|
additionalProperties: false
|
|
|
|
Snapshot:
|
|
type: object
|
|
description: Persistent point-in-time capture of a sandbox.
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique snapshot identifier
|
|
|
|
sandboxId:
|
|
type: string
|
|
description: Source sandbox identifier used to create this snapshot
|
|
|
|
name:
|
|
type: string
|
|
description: Optional human-readable snapshot name
|
|
|
|
status:
|
|
$ref: '#/components/schemas/SnapshotStatus'
|
|
description: Current snapshot lifecycle status and detailed state information
|
|
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
description: Snapshot creation timestamp
|
|
|
|
required:
|
|
- id
|
|
- sandboxId
|
|
- status
|
|
- createdAt
|
|
additionalProperties: false
|
|
|
|
SnapshotState:
|
|
type: string
|
|
description: |
|
|
Snapshot lifecycle state.
|
|
|
|
Common state values:
|
|
- Creating: Snapshot creation has been accepted and runtime capture is in progress.
|
|
- Deleting: Snapshot deletion has been requested and cleanup is in progress.
|
|
- Ready: Snapshot is available for restoring sandboxes.
|
|
- Failed: Snapshot creation failed.
|
|
|
|
Note: New state values may be added in future versions.
|
|
Clients should handle unknown state values gracefully.
|
|
|
|
SnapshotStatus:
|
|
type: object
|
|
description: Detailed snapshot status information with lifecycle state and transition details.
|
|
properties:
|
|
state:
|
|
$ref: '#/components/schemas/SnapshotState'
|
|
description: Current lifecycle state of the snapshot
|
|
|
|
reason:
|
|
type: string
|
|
description: |
|
|
Short machine-readable reason code for the current state.
|
|
Examples: "snapshot_accepted", "snapshot_ready", "snapshot_capture_failed"
|
|
|
|
message:
|
|
type: string
|
|
description: Human-readable message describing the current state or failure reason
|
|
|
|
lastTransitionAt:
|
|
type: string
|
|
format: date-time
|
|
description: Timestamp of the last state transition
|
|
|
|
required: [state]
|
|
additionalProperties: false
|
|
|
|
Sandbox:
|
|
type: object
|
|
description: Runtime execution environment provisioned from a container image or restored from a snapshot
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique sandbox identifier
|
|
|
|
image:
|
|
$ref: '#/components/schemas/ImageSpec'
|
|
description: |
|
|
Container image specification used to provision this sandbox.
|
|
Present when the sandbox was created directly from a container image.
|
|
Not returned in createSandbox response.
|
|
|
|
snapshotId:
|
|
type: string
|
|
description: |
|
|
Snapshot identifier used to restore this sandbox.
|
|
Present when the sandbox was restored from a snapshot.
|
|
Not returned in createSandbox response.
|
|
|
|
platform:
|
|
$ref: '#/components/schemas/PlatformSpec'
|
|
description: |
|
|
Platform constraint echoed from request or workload template.
|
|
Null when no scheduling constraint is provided.
|
|
|
|
status:
|
|
$ref: '#/components/schemas/SandboxStatus'
|
|
description: Current lifecycle status and detailed state information
|
|
|
|
metadata:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Custom metadata from creation request
|
|
|
|
extensions:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Opaque extension data restored from provider-specific storage
|
|
|
|
entrypoint:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: |
|
|
The command to execute as the sandbox's entry process.
|
|
Always present in responses. For image-created sandboxes, this is copied
|
|
from the creation request. For snapshot-created sandboxes, this is restored
|
|
from the snapshot.
|
|
|
|
expiresAt:
|
|
type: string
|
|
format: date-time
|
|
description: Timestamp when sandbox will auto-terminate. Omitted when manual cleanup is enabled.
|
|
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
description: Sandbox creation timestamp
|
|
|
|
required:
|
|
- id
|
|
- status
|
|
- createdAt
|
|
- entrypoint
|
|
SandboxState:
|
|
type: string
|
|
description: |
|
|
High-level lifecycle state of the sandbox.
|
|
|
|
Common state values:
|
|
- Pending: Sandbox is being provisioned
|
|
- Running: Sandbox is running and ready to accept requests
|
|
- Pausing: Sandbox is in the process of pausing
|
|
- Paused: Sandbox has been paused while retaining its state
|
|
- Resuming: Sandbox is being restored after a pause
|
|
- Stopping: Sandbox is being terminated
|
|
- Terminated: Sandbox has been successfully terminated
|
|
- Failed: Sandbox encountered a critical error
|
|
|
|
State transitions:
|
|
- Pending → Running (after creation completes)
|
|
- Running → Pausing (when pause is requested)
|
|
- Pausing → Paused (pause operation completes)
|
|
- Paused → Resuming (when resume is requested)
|
|
- Resuming → Running (when resume operation completes)
|
|
- Running/Paused → Stopping (when kill is requested or TTL expires)
|
|
- Stopping → Terminated (kill/timeout operation completes)
|
|
- Pending/Running/Paused/Resuming → Failed (on error)
|
|
|
|
Note: New state values may be added in future versions.
|
|
Clients should handle unknown state values gracefully.
|
|
SandboxStatus:
|
|
type: object
|
|
description: Detailed status information with lifecycle state and transition details
|
|
properties:
|
|
state:
|
|
$ref: '#/components/schemas/SandboxState'
|
|
description: Current lifecycle state of the sandbox
|
|
|
|
reason:
|
|
type: string
|
|
description: |
|
|
Short machine-readable reason code for the current state.
|
|
Examples: "user_delete", "ttl_expiry", "provision_timeout", "runtime_error"
|
|
|
|
message:
|
|
type: string
|
|
description: Human-readable message describing the current state or reason for state transition
|
|
|
|
lastTransitionAt:
|
|
type: string
|
|
format: date-time
|
|
description: Timestamp of the last state transition
|
|
|
|
required: [state]
|
|
ImageSpec:
|
|
type: object
|
|
required: [uri]
|
|
description: |
|
|
Container image specification for sandbox provisioning.
|
|
|
|
Supports public registry images and private registry images with authentication.
|
|
properties:
|
|
uri:
|
|
type: string
|
|
description: |
|
|
Container image URI in standard format.
|
|
|
|
Examples:
|
|
- "python:3.11" (Docker Hub)
|
|
- "ubuntu:22.04"
|
|
- "gcr.io/my-project/model-server:v1.0"
|
|
- "private-registry.company.com:5000/app:latest"
|
|
|
|
auth:
|
|
type: object
|
|
description: Registry authentication credentials (required for private registries)
|
|
properties:
|
|
username:
|
|
type: string
|
|
description: Registry username or service account
|
|
password:
|
|
type: string
|
|
description: Registry password or authentication token
|
|
additionalProperties: false
|
|
|
|
additionalProperties: false
|
|
PlatformSpec:
|
|
type: object
|
|
required: [os, arch]
|
|
description: |
|
|
Runtime platform constraint used for scheduling/provisioning.
|
|
|
|
This field is independent from `image` and expresses the expected target
|
|
OS and CPU architecture for sandbox execution.
|
|
|
|
Behavioral notes:
|
|
- If omitted, the runtime applies its own default platform selection behavior.
|
|
For Docker, requests are created without an explicit platform override.
|
|
For Kubernetes, no `kubernetes.io/os` or `kubernetes.io/arch` constraint
|
|
is injected unless provided by request or workload template.
|
|
- If provided and cannot be satisfied by runtime/template/pool constraints,
|
|
request must fail explicitly.
|
|
properties:
|
|
os:
|
|
type: string
|
|
enum: [linux, windows]
|
|
description: Target operating system (for example `linux` or `windows`).
|
|
example: linux
|
|
arch:
|
|
type: string
|
|
enum: [amd64, arm64]
|
|
description: Target CPU architecture (for example `amd64` or `arm64`).
|
|
example: arm64
|
|
additionalProperties: false
|
|
PatchSandboxMetadataRequest:
|
|
type: object
|
|
description: |
|
|
JSON Merge Patch (RFC 7396) request body for updating sandbox metadata.
|
|
|
|
The request body is the metadata object itself:
|
|
- Present keys with non-null values add or replace
|
|
- Keys with `null` values are deleted
|
|
- Absent keys are left unchanged
|
|
|
|
Keys with the `opensandbox.io/` prefix are reserved and rejected.
|
|
additionalProperties:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
example:
|
|
project: "new-project"
|
|
team: null
|
|
environment: "production"
|
|
|
|
CreateSandboxRequest:
|
|
type: object
|
|
description: |
|
|
Request to create a new sandbox from either a container image, a snapshot,
|
|
or a pre-configured pool (via `extensions.poolRef`).
|
|
|
|
**Standard mode**: Exactly one of `image` or `snapshotId` must be provided,
|
|
and `resourceLimits` is required.
|
|
|
|
When `image` is provided, `entrypoint` is required. When `snapshotId` is
|
|
provided, `entrypoint` is optional. If omitted, the server defaults the
|
|
sandbox entrypoint to `["tail", "-f", "/dev/null"]`.
|
|
|
|
**Pool mode**: When `extensions.poolRef` is set, the sandbox is created from
|
|
a pre-configured pool. In this case `image`, `entrypoint`, and
|
|
`resourceLimits` are all optional (defined by the Pool CRD template).
|
|
`snapshotId` must not be provided together with `poolRef`.
|
|
|
|
**Note**: API Key authentication is required via the `OPEN-SANDBOX-API-KEY` header.
|
|
properties:
|
|
image:
|
|
$ref: '#/components/schemas/ImageSpec'
|
|
description: |
|
|
Container image specification for the sandbox.
|
|
Mutually exclusive with `snapshotId`.
|
|
|
|
snapshotId:
|
|
type: string
|
|
description: |
|
|
Snapshot identifier to restore from.
|
|
Mutually exclusive with `image`.
|
|
|
|
platform:
|
|
$ref: '#/components/schemas/PlatformSpec'
|
|
description: |
|
|
Optional platform constraint for sandbox scheduling/runtime selection.
|
|
|
|
If omitted, runtime default behavior applies (runtime-specific and not
|
|
a fixed architecture guarantee). If specified, the runtime must satisfy
|
|
this constraint or fail explicitly.
|
|
This field is only meaningful when scheduling constraints are set.
|
|
|
|
timeout:
|
|
oneOf:
|
|
- type: integer
|
|
minimum: 60
|
|
- type: 'null'
|
|
description: |
|
|
Sandbox timeout in seconds. The sandbox will automatically terminate after this duration.
|
|
The maximum is controlled by the server configuration (`server.max_sandbox_timeout_seconds`).
|
|
Omit this field or set it to null to disable automatic expiration and require explicit cleanup.
|
|
Note: manual cleanup support is runtime-dependent; Kubernetes providers may reject
|
|
omitted or null timeout when the underlying workload provider does not support non-expiring sandboxes.
|
|
|
|
resourceLimits:
|
|
$ref: '#/components/schemas/ResourceLimits'
|
|
description: |
|
|
Runtime resource constraints (hard caps) for the sandbox instance.
|
|
Required when `extensions.poolRef` is not set.
|
|
Optional when using pool mode (resource limits are defined by the Pool CRD template).
|
|
SDK clients should provide sensible defaults (e.g., cpu: "500m", memory: "512Mi").
|
|
|
|
resourceRequests:
|
|
$ref: '#/components/schemas/ResourceLimits'
|
|
description: |
|
|
Resource reservations (guaranteed minimums) for the sandbox instance.
|
|
When provided, these values are used as Kubernetes resource `requests`,
|
|
enabling Burstable QoS class (where `requests < limits`).
|
|
When omitted, `resourceLimits` values are used for both limits and requests,
|
|
resulting in Guaranteed QoS class.
|
|
Only meaningful for Kubernetes-based runtimes; ignored by Docker runtime.
|
|
|
|
env:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Environment variables to inject into the sandbox runtime.
|
|
example:
|
|
API_KEY: "secret-key"
|
|
DEBUG: "true"
|
|
LOG_LEVEL: "info"
|
|
|
|
metadata:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: |
|
|
Custom key-value metadata for management, filtering, and tagging.
|
|
Use "name" key for a human-readable identifier.
|
|
example:
|
|
name: "Data Processing Sandbox"
|
|
project: "data-processing"
|
|
team: "ml"
|
|
environment: "staging"
|
|
|
|
entrypoint:
|
|
type: array
|
|
items:
|
|
type: string
|
|
minItems: 1
|
|
description: |
|
|
The command to execute as the sandbox's entry process.
|
|
|
|
Required when `image` is provided.
|
|
|
|
Optional when `snapshotId` is provided. If omitted for snapshot
|
|
restore, the server defaults to `["tail", "-f", "/dev/null"]`.
|
|
|
|
Explicitly specifies the user's expected main process, allowing the sandbox management
|
|
service to reliably inject control processes before executing this command.
|
|
|
|
Format: [executable, arg1, arg2, ...]
|
|
|
|
Examples:
|
|
- ["python", "/app/main.py"]
|
|
- ["/bin/bash"]
|
|
- ["java", "-jar", "/app/app.jar"]
|
|
- ["node", "server.js"]
|
|
example:
|
|
- "python"
|
|
- "/app/main.py"
|
|
|
|
networkPolicy:
|
|
$ref: '#/components/schemas/NetworkPolicy'
|
|
description: |
|
|
Optional outbound network policy for the sandbox.
|
|
Shape matches the sidecar `/policy` endpoint. If omitted or empty,
|
|
the sidecar starts in allow-all mode until updated.
|
|
|
|
credentialProxy:
|
|
$ref: '#/components/schemas/CredentialProxyConfig'
|
|
description: |
|
|
Optional Credential Vault proxy startup settings. Set `enabled: true`
|
|
to enable transparent MITM support for credential injection. Plain
|
|
`networkPolicy` does not enable transparent MITM unless this option
|
|
is set.
|
|
|
|
secureAccess:
|
|
type: boolean
|
|
default: false
|
|
description: |
|
|
Opts the sandbox into secured access for endpoint access.
|
|
This is currently supported only for Kubernetes sandboxes exposed
|
|
through ingress gateway mode. When enabled, the server provisions
|
|
access credentials and returns the required request headers with
|
|
endpoint responses. Clients must include those endpoint headers when
|
|
calling the sandbox. When omitted or false, endpoints remain
|
|
accessible without the additional access token for backward
|
|
compatibility.
|
|
|
|
volumes:
|
|
type: array
|
|
description: |
|
|
Storage mounts for the sandbox. Each volume entry specifies a named backend-specific
|
|
storage source and common mount settings. Exactly one backend type must be specified
|
|
per volume entry.
|
|
items:
|
|
$ref: '#/components/schemas/Volume'
|
|
|
|
extensions:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: |
|
|
Opaque container for provider-specific or transient parameters not supported by the core API.
|
|
|
|
**Note**: This field is reserved for internal features, experimental flags, or temporary behaviors. Standard parameters should be proposed as core API fields.
|
|
|
|
**Best Practices**:
|
|
- **Namespacing**: Use prefixed keys (e.g., `storage.id`) to prevent collisions.
|
|
- **Pass-through**: SDKs and middleware must treat this object as opaque and pass it through transparently.
|
|
|
|
**Well-known keys**:
|
|
- `access.renew.extend.seconds` (optional): Decimal integer string from **300** to **86400** (5 minutes to 24 hours inclusive). Opts the sandbox into OSEP-0009 renew-on-access and sets per-renewal extension seconds. Omit to disable. Invalid values are rejected at creation with HTTP 400 (validated on the lifecycle create endpoint via `validate_extensions` in server `src/extensions/validation.py`).
|
|
ResourceLimits:
|
|
type: object
|
|
description: |
|
|
Runtime resource constraints as key-value pairs. Similar to Kubernetes resource specifications,
|
|
allows flexible definition of resource limits. Common resource types include:
|
|
- `cpu`: CPU allocation in millicores (e.g., "250m" for 0.25 CPU cores)
|
|
- `memory`: Memory allocation in bytes or human-readable format (e.g., "512Mi", "1Gi")
|
|
- `gpu`: Number of GPU devices (e.g., "1")
|
|
|
|
New resource types can be added without API changes.
|
|
additionalProperties:
|
|
type: string
|
|
example:
|
|
cpu: "500m"
|
|
memory: "512Mi"
|
|
gpu: "1"
|
|
RenewSandboxExpirationRequest:
|
|
type: object
|
|
required: [expiresAt]
|
|
properties:
|
|
expiresAt:
|
|
type: string
|
|
format: date-time
|
|
description: |
|
|
New absolute expiration time in UTC (RFC 3339 format).
|
|
Must be in the future and after the current expiresAt time.
|
|
|
|
Example: "2025-11-16T14:30:45Z"
|
|
additionalProperties: false
|
|
RenewSandboxExpirationResponse:
|
|
type: object
|
|
required: [expiresAt]
|
|
properties:
|
|
expiresAt:
|
|
type: string
|
|
format: date-time
|
|
description: |
|
|
The new absolute expiration time in UTC (RFC 3339 format).
|
|
|
|
Example: "2025-11-16T14:30:45Z"
|
|
additionalProperties: false
|
|
ErrorResponse:
|
|
type: object
|
|
description: |
|
|
Standard error response for all non-2xx HTTP responses.
|
|
HTTP status code indicates the error category; code and message provide details.
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: |
|
|
Machine-readable error code (e.g., INVALID_REQUEST, NOT_FOUND, INTERNAL_ERROR).
|
|
Use this for programmatic error handling.
|
|
message:
|
|
type: string
|
|
description: Human-readable error message describing what went wrong and how to fix it.
|
|
required: [code, message]
|
|
additionalProperties: false
|
|
Endpoint:
|
|
type: object
|
|
description: |
|
|
Endpoint for accessing a service running in the sandbox.
|
|
The service must be listening on the specified port inside the sandbox for the endpoint to be available.
|
|
properties:
|
|
endpoint:
|
|
type: string
|
|
description: |
|
|
Public URL to access the service from outside the sandbox.
|
|
Format: {endpoint-host}/sandboxes/{sandboxId}/port/{port}
|
|
Example: endpoint.opensandbox.io/sandboxes/abc123/port/8080
|
|
headers:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: |
|
|
Requests targeting the sandbox must include the corresponding header(s).
|
|
required:
|
|
- endpoint
|
|
additionalProperties: false
|
|
|
|
NetworkPolicy:
|
|
type: object
|
|
description: |
|
|
Egress network policy matching the sidecar `/policy` request body.
|
|
If `defaultAction` is omitted, the sidecar defaults to "deny"; passing an empty
|
|
object or null results in allow-all behavior at startup.
|
|
properties:
|
|
defaultAction:
|
|
type: string
|
|
enum: [allow, deny]
|
|
description: Default action when no egress rule matches. Defaults to "deny".
|
|
egress:
|
|
type: array
|
|
description: List of egress rules evaluated in order.
|
|
items:
|
|
$ref: '#/components/schemas/NetworkRule'
|
|
additionalProperties: false
|
|
|
|
CredentialProxyConfig:
|
|
type: object
|
|
description: |
|
|
Credential Vault proxy startup settings. This is an explicit opt-in for
|
|
transparent MITM support used by credential injection. Credential Vault
|
|
requires `dns+nft` enforcement and a network policy. A deny-default policy
|
|
is strongly recommended; default-allow remains temporarily supported for
|
|
backward compatibility and emits a security warning.
|
|
properties:
|
|
enabled:
|
|
type: boolean
|
|
default: false
|
|
description: |
|
|
When true, the server starts the egress sidecar with transparent
|
|
MITM enabled and installs the runtime-managed MITM CA bundle into
|
|
the sandbox container. Requires `networkPolicy` and server
|
|
`[egress].mode = "dns+nft"`. `defaultAction: deny` is strongly
|
|
recommended; default-allow support is deprecated.
|
|
additionalProperties: false
|
|
|
|
NetworkRule:
|
|
type: object
|
|
properties:
|
|
action:
|
|
type: string
|
|
enum: [allow, deny]
|
|
description: Whether to allow or deny matching targets.
|
|
target:
|
|
type: string
|
|
description: |
|
|
FQDN or wildcard domain (e.g., "example.com", "*.example.com").
|
|
IP/CIDR not yet supported in the egress MVP.
|
|
required: [action, target]
|
|
additionalProperties: false
|
|
|
|
Volume:
|
|
type: object
|
|
description: |
|
|
Storage mount definition for a sandbox. Each volume entry contains:
|
|
- A unique name identifier
|
|
- Exactly one backend struct (host, pvc, ossfs, etc.) with backend-specific fields
|
|
- Common mount settings (mountPath, readOnly, subPath)
|
|
required: [name, mountPath]
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: |
|
|
Unique identifier for the volume within the sandbox.
|
|
Must be a valid DNS label (lowercase alphanumeric, hyphens allowed, max 63 chars).
|
|
pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
|
maxLength: 63
|
|
host:
|
|
$ref: '#/components/schemas/Host'
|
|
pvc:
|
|
$ref: '#/components/schemas/PVC'
|
|
ossfs:
|
|
$ref: '#/components/schemas/OSSFS'
|
|
mountPath:
|
|
type: string
|
|
description: |
|
|
Absolute path inside the container where the volume is mounted.
|
|
Must start with '/'.
|
|
pattern: "^/.*"
|
|
readOnly:
|
|
type: boolean
|
|
description: |
|
|
If true, the volume is mounted as read-only. Defaults to false (read-write).
|
|
default: false
|
|
subPath:
|
|
type: string
|
|
description: |
|
|
Optional subdirectory under the backend path to mount.
|
|
For `ossfs` backend, this field is used as the bucket prefix.
|
|
Must be a relative path without '..' components.
|
|
additionalProperties: false
|
|
|
|
Host:
|
|
type: object
|
|
description: |
|
|
Host path bind mount backend. Maps a directory on the host filesystem
|
|
into the container. Only available when the runtime supports host mounts.
|
|
|
|
Security note: Host paths are restricted by server-side allowlist.
|
|
Users must specify paths under permitted prefixes.
|
|
required: [path]
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: |
|
|
Absolute path on the host filesystem to mount.
|
|
Must start with '/' (Unix) or a drive letter such as 'C:\' or 'D:/'
|
|
(Windows), and be under an allowed prefix.
|
|
pattern: "^(/|[A-Za-z]:[\\\\/])"
|
|
additionalProperties: false
|
|
|
|
PVC:
|
|
type: object
|
|
description: |
|
|
Platform-managed named volume backend. A runtime-neutral abstraction
|
|
for referencing a platform-managed named volume. If `createIfNotExists`
|
|
is true (the default) and the volume does not yet exist, it will be
|
|
created automatically using the provisioning hints below.
|
|
|
|
- Kubernetes: maps to a PersistentVolumeClaim in the same namespace.
|
|
- Docker: maps to a Docker named volume (created via `docker volume create`).
|
|
required: [claimName]
|
|
properties:
|
|
claimName:
|
|
type: string
|
|
description: |
|
|
Name of the volume on the target platform.
|
|
In Kubernetes this is the PVC name; in Docker this is the named
|
|
volume name. Must be a valid DNS label.
|
|
pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
|
|
maxLength: 253
|
|
createIfNotExists:
|
|
type: boolean
|
|
default: true
|
|
description: |
|
|
When true (the default), the volume is automatically created if
|
|
it does not exist. When false, referencing a non-existent volume
|
|
fails with an error.
|
|
deleteOnSandboxTermination:
|
|
type: boolean
|
|
default: false
|
|
description: |
|
|
When true, the volume is automatically removed when the sandbox
|
|
is deleted. Only applies to volumes that were auto-created by the
|
|
server on this request; pre-existing volumes are never removed.
|
|
For Kubernetes, the resulting PVC delete triggers the bound PV's
|
|
StorageClass reclaim policy (`Retain`/`Delete`).
|
|
storageClass:
|
|
type: string
|
|
nullable: true
|
|
description: |
|
|
Kubernetes StorageClass name for auto-created PVCs. Null means
|
|
use the cluster default. Ignored for Docker volumes.
|
|
storage:
|
|
type: string
|
|
nullable: true
|
|
description: |
|
|
Storage capacity request for auto-created PVCs (e.g. "1Gi",
|
|
"10Gi"). Defaults to the server-configured `volume_default_size`
|
|
when omitted. Ignored for Docker volumes.
|
|
pattern: "^\\d+(\\.\\d+)?(Ki|Mi|Gi|Ti|Pi|Ei)?$"
|
|
accessModes:
|
|
type: array
|
|
nullable: true
|
|
items:
|
|
type: string
|
|
description: |
|
|
Access modes for auto-created PVCs (e.g. ["ReadWriteOnce"]).
|
|
Defaults to ["ReadWriteOnce"] when omitted. Ignored for Docker
|
|
volumes.
|
|
additionalProperties: false
|
|
|
|
OSSFS:
|
|
type: object
|
|
description: |
|
|
Alibaba Cloud OSS mount backend via ossfs.
|
|
|
|
The runtime mounts a host-side OSS path under `storage.ossfs_mount_root`
|
|
and bind-mounts the resolved path into the sandbox container.
|
|
Prefix selection is expressed via `Volume.subPath`.
|
|
In Docker runtime, OSSFS backend requires OpenSandbox Server to run on a Linux host with FUSE support.
|
|
required: [bucket, endpoint, accessKeyId, accessKeySecret]
|
|
properties:
|
|
bucket:
|
|
type: string
|
|
description: OSS bucket name.
|
|
minLength: 3
|
|
maxLength: 63
|
|
endpoint:
|
|
type: string
|
|
description: OSS endpoint (e.g., `oss-cn-hangzhou.aliyuncs.com`).
|
|
minLength: 1
|
|
version:
|
|
type: string
|
|
description: ossfs major version used by runtime mount integration.
|
|
enum: ["1.0", "2.0"]
|
|
default: "2.0"
|
|
options:
|
|
type: array
|
|
description: |
|
|
Additional ossfs mount options.
|
|
Runtime encodes options by `version`:
|
|
- `1.0`: mounts with `ossfs ... -o <option>`
|
|
- `2.0`: mounts with `ossfs2 mount ... -c <config-file>` and encodes options as `--<option>` lines in the config file
|
|
Option values must be provided as raw payloads without leading `-`.
|
|
items:
|
|
type: string
|
|
accessKeyId:
|
|
type: string
|
|
description: OSS access key ID for inline credentials mode.
|
|
minLength: 1
|
|
accessKeySecret:
|
|
type: string
|
|
description: OSS access key secret for inline credentials mode.
|
|
minLength: 1
|
|
additionalProperties: false
|