feat: adopt agent-sandbox control plane for tenant workspaces (runc) - #6
Merged
Conversation
Add scripts/setup-agent-sandbox.sh to install the kubernetes-sigs/agent-sandbox controller + CRDs (install commands per the official guide, pinned to v0.4.5 with an override). Add docs/agent-sandbox.md describing the sandbox-first adoption plan, the KEDA->native-hibernation decision, the background-work hibernation hazard + heartbeat mitigation, gVisor-via-SandboxTemplate, and the phased PR delivery. Additive only: does not yet touch the tenant Deployment or KEDA wiring. Refs #365
OpenClaw-shaped runc (default) tier SandboxTemplate. The gVisor tier (PR #2) is the same template plus spec.podTemplate.spec.runtimeClassName: gvisor. Validated on a local kind cluster against agent-sandbox v0.4.5: - setup-agent-sandbox.sh installs controller + CRDs (controller pod Running) - this template passes kubectl apply --dry-run=server against the live CRD - a SandboxClaim referencing a template reconciles to a Running pod Per-tenant SA (Pod Identity) / EFS PVC / config+secret / env are layered at claim time during the tenant migration (next, requires live EKS to validate Bedrock + Pod Identity + EFS). Refs #365
PR#1 of agent-sandbox adoption (#365). Tenant workloads move from Deployment to a per-tenant SandboxTemplate + SandboxClaim (v0.4.x v1alpha1, direct sandboxTemplateRef), runc tier, operatingMode Running (always-on). KEDA scale-to-zero removed; returns later via upstream KEP-968 (ADR-0006). gVisor is a one-value switch for PR#2. - helm: add sandboxtemplate.yaml + sandboxclaim.yaml; gate deployment/hpa/httpscaledobject/referencegrant on sandbox.enabled; httproute backend -> tenant Service in sandbox mode; values sandbox.* - applicationset: switch tenants to sandbox mode (scaleToZero off) - deploy-all.sh: install agent-sandbox controller + CRDs - docs/adr: ADR-0001..0006 (verified vs v0.4.5 CRD + KEP-968) Verified: helm template (both modes) + helm lint pass. Live deploy-verify pending.
… owns headless svc) deploy-verify (hclo-mac/us-east-1) found the agent-sandbox controller creates its own headless Service named after the Sandbox; our same-named ClusterIP Service blocked adoption (ClusterIP immutable). Gate service.yaml off when sandbox.enabled; HTTPRoute backendRef resolves to the controller's Service. Verified live: SandboxClaim -> Template -> Sandbox -> Pod reconciles; controller creates headless Service; pod schedules, EFS PVC binds, all initContainers run, OpenClaw gateway starts. Pod only fails at runtime secret fetch (no Pod Identity assoc / gateway-token for the bare test tenant) -- expected; real tenants get these from the PostConfirmation Lambda.
…-sandbox-control-plane
Merges the ci.yml startup fix (#7) and lints the chart in both legacy and sandbox modes so the new SandboxClaim/SandboxTemplate manifests are validated.
…-sandbox-control-plane
This was referenced Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR #1 of the agent-sandbox adoption tracked in #5. Migrates each tenant
workspace from a plain Deployment to the agent-sandbox SandboxClaim →
SandboxTemplate → Sandbox model (runtime stays runc) and installs the
controller + CRDs as an ArgoCD-managed addon. Every tenant gets a declarative,
lifecycle-managed, kernel-isolatable workspace with a stable identity and
PVC-backed state. The gVisor runtime tier is a follow-up (PR #2).
What's in this PR
scripts/setup-agent-sandbox.sh(wired intodeploy-all.sh) — installscontroller + CRDs, additive
runcSandboxTemplate — full pod spec ported from the tenantDeployment (3 initContainers incl. the Pod Identity IMDS patch, config/skills/
tools, configMap + PVC + tmp volumes, serviceAccount, env),
envVarsInjectionPolicy: Allowed,runtimeClassNamedriven by a valuesandboxTemplateRef)Service gated off so the controller owns the headless Service
Deployment (gated behind
sandbox.*values); ApplicationSet flipped tosandbox mode
docs/adr/0001-0006) + design doc (docs/agent-sandbox.md)What's deferred (and why)
Replicas==0deletes the pod and there is no connection-triggered resume(that lands in v1beta1). This PR runs always-on; scale-to-zero is gated on
upstream Auto Suspend/Resume (Auto Suspend/Resume kubernetes-sigs/agent-sandbox#968) plus a
data-path router. See ADR-0004 / ADR-0006.
Verification (live EKS cluster, us-east-1)
helm template+helm lintpass in both legacy and sandbox modes.SandboxClaim → SandboxTemplate → Sandbox; pod scheduled, EFS PVC (RWX) bound,
all 3 initContainers completed, the workspace gateway started.
Service that collided with the chart's ClusterIP Service (ClusterIP is
immutable → cannot adopt). Fixed by gating the chart Service off in sandbox
mode.
association and gateway-token secret (tenant provisioning, done by the
PostConfirmation Lambda for real tenants), not a manifest defect.
Part of #5
Implements the PR #1 checkbox. PR #2 (gVisor) and PR #1.5 (router + hibernation)
follow.