Sandbox API

Provisioning credentials

Compute quotas always; LLM BYOK via KeyHive or LLM Gateway depending on SANDBOX_LLM_EGRESS.

This page is for tenant/project administrators and Sandbox operators. If you only call Catalog, Harbor, Agent, CodeEdit, or Sandboxes APIs, use Authentication instead.

What Sandbox provisions vs LLM credentials

ConcernWhere
Compute authz (Harbor / Agent / IDE / CodeEdit)Sandbox + Keycloak UMA
Per-project concurrency quotaSandbox Admin /sandbox/v1/admin/quotas/…
LLM BYOK when SANDBOX_LLM_EGRESS=direct + KeyHiveSandbox Admin /sandbox/v1/admin/credential-plane/* → KeyHive
LLM BYOK when SANDBOX_LLM_EGRESS=gatewayLLM Gateway only (ADR 0020)

Modes are exclusive. Dev / preprod / prod Helm default to KeyHive (direct). Flip to Gateway with the env triad in SECRETS.

export SANDBOX_GATEWAY_URL="${SANDBOX_GATEWAY_URL:-http://localhost:8780}"

Set project compute quota

Admin path (break-glass API key + admin key):

curl -sS -X PUT \
  -H "X-Api-Key: $SANDBOX_API_KEY" \
  -H "X-Sandbox-Admin-Key: $SANDBOX_ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"max_concurrent":3}' \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/admin/quotas/acme/proj1"

With Keycloak, an approved administrator can use a Bearer token with the required UMA role instead of the break-glass pair (see Authentication).

Set a tenant-wide fallback with project _default:

curl -sS -X PUT \
  -d '{"max_concurrent":2}' \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/admin/quotas/acme/_default"

An exact project policy wins over the tenant default, which wins over the environment default. The operator ceiling may reject a value that exceeds safe fleet capacity.

The consumer can inspect its effective quota without admin privilege:

curl -sS -H "X-Api-Key: $SANDBOX_API_KEY" \
  -H "X-Sandbox-Tenant-Id: acme" \
  -H "X-Sandbox-Project-Id: proj1" \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/quota"

LLM provider keys — KeyHive mode

When the cluster runs KeyHive (SANDBOX_LLM_EGRESS=direct, SANDBOX_CREDENTIAL_BACKEND=keyhive, KEYHIVE_BASE_URL set):

# Ensure team for tenant:project
curl -sS -X POST \
  -H "X-Api-Key: $SANDBOX_API_KEY" \
  -H "X-Sandbox-Admin-Key: $SANDBOX_ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"namespace":"acme:proj1","keys":{}}' \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/admin/credential-plane/teams"

# Append a provider key
curl -sS -X POST \
  -H "X-Api-Key: $SANDBOX_API_KEY" \
  -H "X-Sandbox-Admin-Key: $SANDBOX_ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"namespace":"acme:proj1","provider":"anthropic","key":"'"$PROVIDER_API_KEY"'"}' \
  "$SANDBOX_GATEWAY_URL/sandbox/v1/admin/credential-plane/keys"

Harbor / Agent / Cloud IDE then lease keys from KeyHive for that namespace. GET /sandbox/v1/providers reflects the pool.

LLM provider keys — Gateway mode

When SANDBOX_LLM_EGRESS=gateway, do not POST provider secrets to Sandbox — those admin routes return HTTP 410. Configure BYOK, workspaces, and budgets in LLM Gateway. Harbor / Agent use Keycloak M2M (sandbox-{env} → audience includes llm-gateway).

Cloud IDE gets Gateway base-URL hints only — trainers authenticate to LLM Gateway themselves (no vendor keys injected).

Next