Skip to main content

C-12 Execution Sandbox

Brick C: Agents, autonomy, execution. French version: C-12-execution-sandbox

1. Role and responsibilities​

Runs untrusted code and tools in isolated gVisor or Kata Containers pods, without network by default.

  • Isolation profiles (runtimeClass gvisor, kata)
  • Egress denied except allow list
  • Collect stdout, files, exit code

2. Position in the architecture and interactions​

  • Callers: Tool Gateway (sandbox_profile), Plugin Runtime (D-08).
  • Execution path: Asynchronous: creation then polling.
  • Every interaction goes through the Control Plane API v1 (/v1) behind the API Gateway (D-14).

3. Open source component and developed part​

  • Open source: gVisor, Kata Containers, Kubernetes
  • Developed: Execution API, profiles, result collection.
  • External integration through an adapter eai/integrations/<system>.py with an in-process fallback when the URL is not configured.

4. Data model​

Tables (schema eai, tenant_id RLS):

  • eai.sandbox_executions

Common columns: id uuid, tenant_id uuid NOT NULL, created_at, updated_at; RLS policy current_setting('app.tenant_id', true)::uuid.

5. Contract​

  • Applied contract: tool-manifest
  • JSON Schema: contracts/v1/tool-manifest.schema.json
  • Key fields: spec.sandbox_profile
  • Validation: POST /v1/contracts/{name}/validate; manifest apply: POST /v1/manifests/apply.

6. API endpoints​

  • POST /v1/sandbox/executions
  • GET /v1/sandbox/executions/{id}

Request POST /v1/sandbox/executions:

{
"profile": "gvisor-small",
"image": "python:3.12-slim",
"command": [
"python",
"-c",
"print(2+2)"
],
"limits": {
"cpu": "500m",
"memory": "256Mi",
"timeout_s": 30
}
}

Response:

{
"id": "sbx_5",
"status": "running"
}

7. SDK examples​

Python:

from enterprise_ai import EnterpriseAI

client = EnterpriseAI(base_url="<control-plane-url>", api_key="eai_xxx_secret")
ex = client.sandbox.execute("python:3.12-slim", ["python", "-c", "print(1)"], profile="gvisor")

TypeScript:

import { EnterpriseAI } from "@enterprise-ai/sdk";

const client = new EnterpriseAI({ baseUrl: "<control-plane-url>", apiKey: process.env.EAI_API_KEY });
const ex = await client.sandbox.execute({ image: "python:3.12-slim", profile: "gvisor", command: ["python", "-c", "print(1)"] });

Java:

EnterpriseAIClient client = EnterpriseAIClient.builder()
.baseUrl("<control-plane-url>")
.apiKey(System.getenv("EAI_API_KEY"))
.build();
JsonNode ex = client.sandbox().execute(Map.of("image", "python:3.12-slim", "command", List.of("python", "-c", "print(1)"), "profile", "gvisor"));

Go:

c, _ := eai.NewClient(eai.WithBaseURL("<control-plane-url>"), eai.WithAPIKey(os.Getenv("EAI_API_KEY")))
ex, _ := c.Sandbox.Execute(ctx, map[string]any{"image": "python:3.12-slim", "profile": "gvisor-small"})

8. Configuration​

  • Environment variables: EAI_SANDBOX_NAMESPACE_PREFIX, EAI_DATABASE_URL
  • Helm values keys: sandbox.enabled, sandbox.runtimeClass, sandbox.networkPolicy.egress

9. Security controls​

  • No service token mounted, no secret
  • NetworkPolicy deny all
  • Read only filesystem except /tmp
  • Every request carries the tenant resolved from the credential; PostgreSQL RLS
  • Every mutation and policy decision writes a hash-chained audit event

10. Observability​

  • Prometheus metrics: eai_sandbox_executions_total{profile}, eai_sandbox_cpu_seconds, eai_sandbox_duration_seconds
  • Traces: OpenTelemetry spans with GenAI semantic conventions (gen_ai.operation.name, gen_ai.agent.id, gen_ai.tool.name), attributes eai.tenant_id, eai.run_id, traceparent propagation.
  • Audit actions: sandbox.execute

11. FinOps units​

  • CPU seconds, memory MB seconds, execution duration per profile.
  • Emitted as Usage Event (POST /v1/finops/usage) with tenant, project, agent and run.

12. Failure modes and resilience​

  • Timeout -> pod killed, status timeout
  • OOM -> status oom_killed
  • Normalized errors (error envelope, message_i18n en/fr)

13. Standalone adoption (client of a client)​

  • enterprise_ai.sandbox + Kubernetes with gVisor runtimeClass.
  • SDK: enterprise_ai.agent (AgentsClient, RunsClient, SessionsClient)
  • Minimal deployment: Helm chart with controlPlane.enabled=true and PostgreSQL; disabled external components use their in-process fallback.

14. Acceptance tests​

  1. Outbound network blocked
  2. Timeout honoured
  3. Cross-tenant access refused
  4. Error returned in fr with Accept-Language: fr

Kit L3 proof​

gVisor: sandbox.run_untrusted runs untrusted tool code with runsc --rootless --network=none do (release 20261026.0 fetched and sha512 verified by tools/runtime/fetch.sh, EAI_SANDBOX_RUNSC overrides the path). Fail closed: when runsc is missing or cannot start, the code is refused and never runs on the host. Proof: tests/test_runtime_gvisor_sandbox.py (host write invisible, network refused, refusal when the sandbox is unavailable).