Update AGENT_SANDBOX_VERSION to v1.0.8 and the docs that quote the control-plane pin (example prerequisites, architecture, versioning table, minimal-single-tenant template comment, platform skill). The v1.0.8 release adds only one CRD field, spec.failedPodPolicy (Sandbox and SandboxTemplate, enum Retain|Recreate, default Retain), so the existing manifests keep their behavior: Retain is the default and neither the API version (v1beta1) nor any field we set changed. All five custom resources still validate against the v1.0.8 CRD schemas. Behavior changes in the controller itself (bounded MCP output, router kustomization, creation-latency metric timing) do not affect the platform because it uses neither the sandbox-router nor the MCP server. Co-authored-by: SREDevOpsAgents <agents@sredevops.org>
7.8 KiB
name, description, whenToUse, metadata
| name | description | whenToUse | metadata | ||||
|---|---|---|---|---|---|---|---|
| dsh-agent-sandbox-platform | Operate and extend this repository's DeepSeek Harness-on-agent-sandbox platform: warm pools, claims, sandbox suspend/resume, the gateway, and the optional agent-sandbox MCP server, with version-aware safety and a read-only preflight. | Use when working in deepseek-kubernetes-sandbox or with Kubernetes agent-sandbox: inspect or provision sandboxes, debug warm pools or claims, use mcp__*__create_sandbox/execute_command, connect the agent-sandbox MCP server, or add a manifest, gateway route, exposure variant, example, or version bump here. |
|
DSH agent-sandbox platform
This repository runs DeepSeek Harness Web (DSH) as one sandbox per user on
agent-sandbox, with an
optional official MCP server for sandbox execution. For generic cluster work
load kubernetes-kubectl-operations; for profile MCP rows load
cordis-plugin-development.
0. Facts before action
- Read
AGENTS.md,versions.env, the example README/architecture. The control-plane pin isAGENT_SANDBOX_VERSION; release identity isDSH_VERSION+RELEASE_REVISION. - Establish context, user and namespace; never assume
dsh-demo. - Run
scripts/platform-preflight.sh --namespace <ns>(read-only). - If
mcp__*__create_sandbox-style tools are absent, usekubectl; do not install or enable a server on your own.
1. Non-negotiables
- Read-only by default. Change a cluster only when the user asked for that exact change; show the command and rollback first.
- Scope every command with
--contextand-n.--all/-Amutations and deleting namespaces, PVCs, PVs, CRDs, or cluster-scoped objects need an explicit, named confirmation. - Secrets and logs stay private. Never print Secret data, kubeconfigs, or node logs. Pod logs can contain the DSH launch token.
- The MCP server has no authentication. It is a full-access management endpoint; never expose it. A DSH profile row affects every session.
- Clean up what you create. Delete MCP-created sandboxes in the same session; never leave orphaned claims running.
- Bound output. Use
--tail,--since, selectors, JSONPath, and head/tail excerpts instead of whole manifests or huge logs.
2. Choose the path
| Need | Path |
|---|---|
| Inspect or change claims, pools, sandboxes, PVCs, gateway | kubectl + platform runbook |
| Run code or move files in a sandbox | agent-sandbox MCP, only for a runtime-capable template (MCP reference) |
| Add or change a repository feature | repo extension guide |
The MCP server cannot manage this example's DSH claims: its tools are scoped to
claims created by the same MCP session. Use kubectl for the platform.
3. Operate the platform
Resolve user -> claim -> sandbox -> pod:
SB=$(kubectl -n "$NS" get sandboxclaim "$CLAIM" -o jsonpath='{.status.sandbox.name}')
kubectl -n "$NS" get sandbox "$SB" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}{" "}{.status.conditions[?(@.type=="Ready")].reason}{"\n"}{.status.serviceFQDN}{"\n"}'
POD=$(kubectl -n "$NS" get sandbox "$SB" -o jsonpath='{.metadata.annotations.agents\.x-k8s\.io/pod-name}'); POD=${POD:-$SB}
- Read runtime state from the Sandbox, not the claim:
spec.operatingMode,Suspended,Ready. The claim tracks binding, not liveness. - Suspend = patch
operatingMode: Suspended(pod deleted, PVC + Service kept); resume =Running+ wait forReady. The gateway wakes on connect. - Warm-pool spares carry
agents.x-k8s.io/warm-pool-sandbox; adopted sandboxes lose it. A pool with no spares makes signup cold and slow. - The DSH launch token appears once in pod logs; hand the user the
?token=URL, never the token in reports. Probe/favicon.svg. - The idle sweeper only suspends claims the gateway created.
Full commands, security boundaries and failure matrix: platform runbook.
4. Use the agent-sandbox MCP server within its limits
Verified from the upstream server:
- Tools:
create_sandbox,delete_sandbox,execute_command,upload_file,download_file,list_files,file_exists,get_sandbox_status; resourcesandboxes://{namespace}. - Session-scoped: every tool and the resource filter claims by
K8S_SANDBOX_SESSION_ID_LABEL_KEY=<MCP session id>. It cannot read, exec in, or delete DSH platform claims or claims from a prior/reconnected session. - Streamable HTTP only: stdio has no MCP session id and fails. A DSH row must
use
transport: streamable-http; health endpoints are/healthzand/readyzat the root, the MCP endpoint is/mcp. - Runtime required: connection types target a sandbox runtime on 8888, or
sandboxd on 8080/9090. The DSH template listens only on 3080, so
execute_commandcannot work against it. A sandboxd sidecar executes in its own container, not DSH's. - Timeouts:
create_sandboxwaits up to 180 s, but the DSH MCP client's default call timeout is 60 s; raisetoolCallTimeoutMs.shutdown_after_secondsdefaults to 300 s (nulldisables it). - Output: servers before v1.0.8 return unbounded
execute_commandoutput. v1.0.8 addsmax_output_chars(128-300,000, default 30,000) and truncation metadata. The repository pins v1.0.8 (AGENT_SANDBOX_VERSION), so the documented deployment is bounded; never pass the new argument to an older server, and on one redirect verbose output and read a file instead.
Deployment, connection matrix and DSH row: MCP deployment. Limits and cleanup: MCP reference.
5. Extend the project
Read docs/examples.md and the testing table in AGENTS.md before editing.
- Manifest step: numbered
manifests/NN-*.yaml, update the README step, runmake check; CI dry-runs it. - Gateway: edit
gateway/gateway.pyandgateway/test_gateway.py, update the gateway README API table and architecture doc, runmake testandmake lint. Keep the HTTP/WebSocket contract stable. - Exposure variant: one variant under
manifests/exposure/<variant>/, update the exposure README and trusted-host/cookie settings. Variants are alternatives, never a stack. - New example: follow
docs/examples.md, add the index entry, keep scripts executable/idempotent/self-cleaning, runmake check. - Version bump: edit
versions.envonly, update prerequisites, runmake checkand the e2e. Never mix a bump with an unrelated feature. - MCP integration: pin the build to the cluster's tag, least-privilege SA, ClusterIP + auth proxy, raised DSH timeout, no secrets in the repo.
- Optional hardening: gVisor,
nodeSelector, NetworkPolicy and extra provider keys stay opt-in; the sandbox policy lives undermanifests/optional/. All four are documented inexamples/dsh-agents-as-a-service/docs/optional-hardening.md. - Docs: update the affected doc in the same change.
Details and review checklist: repo extension guide.
6. Report and clean up
State context/namespace, bounded evidence, conclusion, exact change, rollback, and resources deleted. Disable any MCP row enabled only for the task. Do not leave sandboxes, port-forwards, or temporary files behind.