driver

package
v0.0.0-...-43adcfd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: AGPL-3.0 Imports: 51 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RuntimeDriverBoxlite      = "boxlite"
	RuntimeDriverDocker       = "docker"
	RuntimeDriverMicrosandbox = "microsandbox"
	RuntimeDriverK8s          = "k8s"
)
View Source
const (
	MetricUnitPercent = "percent"
	MetricUnitBytes   = "bytes"
	MetricUnitSeconds = "seconds"
)
View Source
const (
	MetricStatusOK          = "ok"
	MetricStatusUnknown     = "unknown"
	MetricStatusUnavailable = "unavailable"
)
View Source
const DirectoryOnlyGuestSandboxPath = directoryOnlyGuestSandboxPath

Variables

View Source
var (
	// ErrGuestRuntimeNotReady means the guest runtime has not installed its
	// signal handler and published its PID yet.
	ErrGuestRuntimeNotReady = errors.New("guest runtime is not ready for signals")
	// ErrGuestRuntimeGone means the ready file no longer identifies the
	// tracked agent-compose-runtime process.
	ErrGuestRuntimeGone = errors.New("guest runtime is no longer running")
)
View Source
var ErrExecTerminationUnconfirmed = errors.New("guest execution termination unconfirmed")

ErrExecTerminationUnconfirmed means a runtime driver returned without being able to prove that the guest execution it started has stopped.

View Source
var ErrRuntimeCapabilityUnsupported = errors.New("runtime capability unsupported")

ErrRuntimeCapabilityUnsupported reports that the sandbox-host runtime does not implement an optional capability (stats, liveness, guest signals, or process tree termination). It is distinct from ErrRuntimeInteractionUnsupported, which is specific to the interaction surface: mapping every Unimplemented code to the interaction sentinel would make a "stats unsupported" refusal look like an interaction refusal.

View Source
var ErrRuntimeDriverNotCompiled = errors.New("runtime driver not compiled")

ErrRuntimeDriverNotCompiled identifies a runtime driver that the product recognizes but the current binary was not built to support.

View Source
var ErrRuntimeInteractionUnsupported = errors.New("runtime interaction unsupported")
View Source
var ErrSandboxNetworkEnforcementUnavailable = errors.New("sandbox network enforcement unavailable")

ErrSandboxNetworkEnforcementUnavailable reports a declared restricting policy the selected driver cannot enforce. It is returned instead of starting a sandbox with unrestricted egress.

Functions

func CleanupBoxliteVolumeBridgeMounts

func CleanupBoxliteVolumeBridgeMounts(sessionDir string) error

CleanupBoxliteVolumeBridgeMounts releases host-side bridge mounts under a session directory. It is safe to call for sessions that do not use BoxLite or do not have volume bridges.

func CompiledRuntimeDrivers

func CompiledRuntimeDrivers() []string

CompiledRuntimeDrivers returns the runtime drivers included in this binary. The result is ordered and may be modified by the caller.

func DecideSandboxNetworkEgress

func DecideSandboxNetworkEgress(policy SandboxNetworkPolicy, endpoint egress.Endpoint) (egress.Result, error)

DecideSandboxNetworkEgress evaluates one destination through the engine decision model, so a driver or a test never hand-rolls allow/deny logic.

func DefaultGuestImageForDriver

func DefaultGuestImageForDriver(config *appconfig.Config, driver string) string

func EnsureDockerImage

func EnsureDockerImage(ctx context.Context, imageRef string) (string, error)

func GuestRuntimeControlEnv

func GuestRuntimeControlEnv(env map[string]string, executionID string) map[string]string

GuestRuntimeControlEnv copies env and installs the private host/guest runtime identity used by graceful-stop control operations.

func IsHeldCredentialName

func IsHeldCredentialName(name string) bool

IsHeldCredentialName reports whether the daemon holds name's value alone, so a user-facing view must not echo it.

The distinction is deliberate and mirrors the existing LLM rule: the daemon redacts a name only when the value never reaches the guest. A recognized but not-yet-absorbed credential (git, MCP, registry) still travels as plaintext environment, and hiding it from a view would describe an exposed value as protected without changing the exposure. CredentialEnvName enumerates those forms so the broker can absorb them; until then the declaration stays the visible source of truth.

func IsRuntimeDriverCompiled

func IsRuntimeDriverCompiled(value string) bool

IsRuntimeDriverCompiled reports whether the normalized runtime driver is included in this binary.

func JupyterConnectAddress

func JupyterConnectAddress(proxyState ProxyState) string

func JupyterConnectTarget

func JupyterConnectTarget(proxyState ProxyState) (host string, port int)

func LLMProviderCredentialEnvName

func LLMProviderCredentialEnvName(name string) bool

LLMProviderCredentialEnvName reports whether name carries provider credential material. It is the single list of credential names the daemon keeps off a guest, and it also decides whether a view of a declaration may echo the value: a name on this list never reaches the guest, so the daemon holds it alone and a user-facing response must not return it.

Every credential the facade can absorb belongs here, including the aliases a vendor accepts (CODEX_API_KEY for an OpenAI credential), and so does every credential the daemon recognizes but cannot proxy. The list is exhaustive for recognition: a name the daemon does not recognize is deliberately absent, because that value is passed through to the guest, so a view that hid it would describe an exposed value as protected without changing the exposure.

func LLMProviderEnvName

func LLMProviderEnvName(name string) bool

LLMProviderEnvName reports whether name is long-lived LLM provider configuration that must never be passed through to a guest runtime. It is the canonical denylist shared by driver env assembly and the facade layer.

It covers the endpoint variables as well as the credentials, because both belong to the declaration the daemon absorbs: once an agent or project declares an upstream, the daemon holds the address and the key, and the guest is given the facade address and a run-scoped token instead. Leaving the declared endpoint behind would hand the guest an address it can no longer authenticate against, which is a confusing failure rather than a useful capability.

func NewRuntimeCacheSources

func NewRuntimeCacheSources(config *appconfig.Config) []cache.Source

func NewRuntimeInteractionUnsupportedError

func NewRuntimeInteractionUnsupportedError(driver string, spec RuntimeStartSpec, capability RuntimeInteractionCapability, reason string) error

func ReapBoxliteShimProcesses

func ReapBoxliteShimProcesses(runtimeHome, boxID string) (bool, error)

ReapBoxliteShimProcesses terminates the detached VM shim a failed boxlite start left behind, and reports whether it terminated one.

boxlite reports a failed start without releasing the shim or the bwrap jail around it, and both keep the VM's /dev/kvm handle open: repeated failures accumulate handles until the host's kvm module can no longer be unloaded (test round D2b). Releasing the process is therefore the caller's job.

The signal is only sent to a process that runs the runtime's own shim binary, because a pid recorded for a box that has since been removed must never become a signal to an unrelated process that reused the id. Callers reap immediately after a failed start, while the pid is current.

It is exported because its only caller is the cgo boxlite start path, which is compiled out of builds that do not include that driver.

func RemoveDockerManagedResource

func RemoveDockerManagedResource(ctx context.Context, config *appconfig.Config, resource ManagedRuntimeResource) error

func RequireSandboxNetworkEnforcement

func RequireSandboxNetworkEnforcement(driver, sandboxID string, policy *SandboxNetworkPolicy, mode config.EgressUnenforceablePolicy) error

RequireSandboxNetworkEnforcement applies the configured policy to a sandbox that declares restricting egress on a driver that cannot apply any part of it. A nil or non-restricting policy returns nil: an undeclared policy keeps today's behavior (D3), so this gate never tightens a sandbox that did not ask for it.

A restriction the driver cannot deliver must not become an availability failure, so the default (warn) starts the sandbox and reports that the declaration is unenforced; refuse is opt-in for deployments that require the declaration to be real. Either way the sandbox is never presented as constrained when it is not.

func ResolveRuntimeDriver

func ResolveRuntimeDriver(value string) string

func ResolveSandboxGuestImage

func ResolveSandboxGuestImage(values ...string) string

func ResolveSandboxRuntimeDriver

func ResolveSandboxRuntimeDriver(value, fallback string) (string, error)

func RuntimeDriverSupportsStoppedRuntimeRetention

func RuntimeDriverSupportsStoppedRuntimeRetention(driver string) bool

RuntimeDriverSupportsStoppedRuntimeRetention reports whether a driver can stop a sandbox while preserving the same private writable runtime for a later resume. Kubernetes Pods have no stopped-but-retained lifecycle state: stopping a Pod deletes it, and resume creates a new Pod from the image.

func RuntimeHomeForDriver

func RuntimeHomeForDriver(config *appconfig.Config, driver string) string

func RuntimeRefPrefix

func RuntimeRefPrefix(driver string) string

RuntimeRefPrefix returns the prefix sandboxstore uses to precompute a new sandbox's RuntimeRef (and, for every driver, the resulting container/Pod name each driver's own naming fallback would otherwise compute) before the driver itself has run. The k8s driver's Pod name is deliberately prefixed "agent-compose-sandbox-" rather than bare "agent-compose-" so it reads distinctly from the daemon's own Deployment-managed Pod name in a plain `kubectl get pods` (see k8sRuntime.podName) - this must return the same prefix that fallback would, or the precomputed RuntimeRef silently wins over it via firstNonEmpty and the k8s-specific naming never takes effect.

func SandboxNetworkEgressPolicy

func SandboxNetworkEgressPolicy(policy SandboxNetworkPolicy) (egress.Policy, error)

SandboxNetworkEgressPolicy compiles a driver-boundary policy into the engine egress model through the declaration layer's compiler, so endpoint matching, engine-endpoint precedence, and the generation stamped on every decision are exactly the ones the rest of the engine uses.

func SandboxStopContextTimeout

func SandboxStopContextTimeout(driver string, stopTimeout time.Duration) time.Duration

func ServeSandboxHost

func ServeSandboxHost(ctx context.Context, config *appconfig.Config) error

ServeSandboxHost constructs the VM runtimes in-process and serves the sandbox-host gRPC service on the configured unix socket until ctx is cancelled. It is the process body of `agent-compose sandbox-host`.

func ValidateCompiledRuntimeDriver

func ValidateCompiledRuntimeDriver(value string) error

ValidateCompiledRuntimeDriver validates both the runtime driver name and whether support for that driver is included in this binary.

func ValidateRuntimeDriver

func ValidateRuntimeDriver(value string) error

func WaitForJupyterProxy

func WaitForJupyterProxy(ctx context.Context, proxyState ProxyState) error

Types

type AgentNetworkPolicyReport

type AgentNetworkPolicyReport struct {
	// Agent is the project-local agent name the declaration belongs to.
	Agent string
	// Driver is the resolved runtime driver the report was computed for.
	Driver string
	// Declared is false when neither the agent nor the daemon declared a network
	// policy. Undeclared is not deny (D3): egress stays unrestricted and there
	// is nothing to enforce. A daemon-wide policy sets it true for every agent,
	// including one that declared nothing itself.
	Declared bool
	// Restricts is false when the declaration cannot refuse anything: an allow
	// default with no denial. It is true for a deny default or any declared
	// denial, and false for an undeclared policy.
	Restricts bool
	// Default is the action applied to traffic no entry matches.
	Default egress.Action
	// Allow lists the declared allowances, including their address ranges.
	Allow []egress.DeclaredAllowance
	// Deny lists the declared refusals.
	Deny []egress.DeclaredDenial
	// Mediated reports whether the engine's own forward proxy will apply the
	// declaration rather than the driver.
	Mediated bool
	// Enforcement is the mechanism that will apply the declaration.
	Enforcement SandboxNetworkEnforcement
	// Enforced reports whether that mechanism applies the declaration.
	Enforced bool
	// Mechanisms lists every enforcement mechanism that will apply at least part
	// of this declaration, in driver-first order: for example
	// ["sdk_network_policy", "forward_proxy"]. Mechanism above remains the one
	// that determines the reported strength, so a consumer that only knows the
	// primary mechanism keeps its existing interpretation.
	Mechanisms []string
	// Limitations states material limits of the reported enforcement that do not
	// make it unenforced, such as traffic that bypasses the forward proxy. It is
	// empty when there is nothing beyond Mechanism to disclose.
	Limitations []string
	// DaemonPolicySource and DaemonPolicySHA256 identify the daemon-wide policy
	// the effective declaration was computed against. They are empty when no
	// daemon-wide policy was configured, or when this report was produced
	// outside project admission.
	DaemonPolicySource string
	DaemonPolicySHA256 string
	// Unapplied names the parts of the declaration the mechanism does not apply.
	// It is empty when the mechanism applies all of it.
	Unapplied []string
	// Warning states what the operator must know when the declaration will not be
	// enforced as written. It is empty when it will be.
	Warning string
}

AgentNetworkPolicyReport is the auditable account of one agent's declared outbound network policy and the mechanism that will apply it.

func ReportAgentNetworkPolicy

func ReportAgentNetworkPolicy(agent, driver string, declaration *egress.NetworkDeclaration, mediated bool, mode config.EgressUnenforceablePolicy) (AgentNetworkPolicyReport, error)

ReportAgentNetworkPolicy accounts for one agent's declared policy on one resolved driver. mediated reports whether the engine's forward proxy will be in this sandbox's traffic path; mode is the deployment's EGRESS_UNENFORCEABLE_POLICY, which decides what an unenforceable declaration means so the report can state the outcome instead of restating the knob.

A nil declaration reports Declared false: the engine cannot restrict a sandbox that did not ask, so there is no mechanism to name and no gap to report.

type CredentialSurface

type CredentialSurface struct {
	// Kind is the credential form the name belongs to.
	Kind credentials.Kind
	// Absorbable reports whether the daemon can already replace the declared
	// plaintext value with a short-lived, scoped handle on the way into a
	// sandbox. Only the LLM facade is absorbable today: the daemon holds the
	// upstream key and gives the guest a run-scoped facade token. Git, MCP, and
	// registry credentials are recognized, but still travel as plaintext
	// environment until the credential broker has a declared endpoint to scope
	// them to; they stay visible in views and are reported as not yet isolated
	// instead of being described as protected.
	Absorbable bool
}

CredentialSurface classifies a declared environment variable or MCP header that carries a long-lived credential.

The engine's credential surface used to be implicit: LLM provider keys were recognized by name because the facade absorbed them, and everything else was simply not modeled. This type makes the whole surface explicit so a recognized credential can be redacted from views and reported honestly, rather than appearing to be protected because nothing named it.

func CredentialEnvName

func CredentialEnvName(name string) (CredentialSurface, bool)

CredentialEnvName reports whether name is a recognized long-lived credential and which handle kind it maps to.

It generalizes LLMProviderCredentialEnvName rather than replacing it: the LLM predicate stays the single list of provider credential names that pkg/llms is checked against, and this function adds the non-LLM forms the engine recognizes. MCP servers carry headers as well as environment (Authorization, X-API-Key, ...), so the same table answers for both; the names are compared case-insensitively after trimming.

type ExecChunk

type ExecChunk struct {
	// Text is valid UTF-8. Runtime byte streams must buffer incomplete rune
	// suffixes and replace irrecoverably invalid input before emitting a chunk.
	Text   string
	Stream StdioStream
}

type ExecResult

type ExecResult struct {
	ExitCode int
	Stdout   string
	Stderr   string
	Output   string
	Success  bool
	// SecurityFacts carries the isolation failures the lower layer reported on
	// this exec's stderr. It is engine-measured evidence, not a driver
	// declaration, and is zero when the lower layer reported nothing.
	SecurityFacts ExecSecurityFacts
}

type ExecSecurityFacts

type ExecSecurityFacts struct {
	// SeccompUnavailable counts reports that seccomp privileges were not set.
	SeccompUnavailable int `json:"seccomp_unavailable,omitempty"`
	// NoNewPrivilegesUnavailable counts reports that no_new_privileges was not
	// enforced.
	NoNewPrivilegesUnavailable int `json:"no_new_privileges_unavailable,omitempty"`
}

ExecSecurityFacts counts the isolation-enforcement failures a lower layer reported on one exec's stderr. A nonzero count is engine-measured evidence: the engine did not ask a driver whether it was ready, it observed the lower layer say it failed. pkg/capmatrix turns these into unsupported capability assertions.

func (ExecSecurityFacts) IsZero

func (f ExecSecurityFacts) IsZero() bool

IsZero reports whether the lower layer reported no isolation failure.

func (ExecSecurityFacts) Merge

Merge returns the sum of two observations, so facts gathered across several exec calls or several concurrent streams accumulate instead of overwriting.

func (ExecSecurityFacts) Pointer

func (f ExecSecurityFacts) Pointer() *ExecSecurityFacts

Pointer returns a pointer to a copy of the facts, or nil when the lower layer reported no isolation failure. It keeps the optional field out of a result JSON payload when there is nothing to report.

func (ExecSecurityFacts) Total

func (f ExecSecurityFacts) Total() int

Total returns how many isolation failures were observed.

type ExecSpec

type ExecSpec struct {
	Command string            `json:"command"`
	Args    []string          `json:"args,omitempty"`
	Env     map[string]string `json:"env,omitempty"`
	Cwd     string            `json:"cwd,omitempty"`
	// Marker, when set, tags the exec's process tree with this value instead
	// of a driver-generated one. The daemon uses a run's execution id as the
	// marker for a detached task so it can later terminate that exact tree via
	// ProcessTreeTerminator, independent of any exec handle.
	Marker string `json:"marker,omitempty"`
	// KillOnlyOnCancel reports that this exec is a single attach process whose
	// process tree is not the task's. On context cancellation the driver must
	// kill the exec directly and skip the whole-tree termination cleanup (which
	// otherwise adds a bounded SIGTERM→SIGKILL escalation on VM drivers).
	KillOnlyOnCancel bool `json:"kill_only_on_cancel,omitempty"`
}

func ExecSpecFromRuntimeStartSpec

func ExecSpecFromRuntimeStartSpec(spec RuntimeStartSpec) ExecSpec

type ExecStreamInteractionRequest

type ExecStreamInteractionRequest struct {
	Session *Sandbox
	VMState VMState
	Spec    RuntimeStartSpec
}

ExecStreamInteractionRequest describes the sandbox and command to stream-exec.

type ExecStreamWriter

type ExecStreamWriter func(ExecChunk)

type GuestDirectoryPublication

type GuestDirectoryPublication struct {
	HostSource       string
	GuestDestination string
	ManagedMarker    string
}

GuestDirectoryPublication describes a private guest directory publication. ManagedMarker identifies a legacy directory that this caller owns.

type GuestSymlinkProjection

type GuestSymlinkProjection struct {
	GuestPath      string
	RelativeTarget string
	ManagedMarkers []string
}

GuestSymlinkProjection describes an alias inside the private guest home. ManagedMarkers name caller-owned legacy formats; unrelated paths are refused.

type ManagedRuntimeResource

type ManagedRuntimeResource struct {
	Driver         string
	RuntimeID      string
	SandboxID      string
	UpdatedAt      time.Time
	OwnershipValid bool
	Removable      bool
	BlockedReasons []string
	OwnedPaths     []string
}

func ListDockerManagedResources

func ListDockerManagedResources(ctx context.Context, config *appconfig.Config) ([]ManagedRuntimeResource, error)

func ListMicrosandboxManagedResources

func ListMicrosandboxManagedResources(context.Context, *appconfig.Config) ([]ManagedRuntimeResource, []string, error)

type MetricValue

type MetricValue struct {
	Value   *float64
	Unit    string
	Status  string
	Message string
}

type ProcessTreeTerminator

type ProcessTreeTerminator interface {
	TerminateProcessTree(context.Context, *Sandbox, VMState, string) error
}

ProcessTreeTerminator is an optional SandboxRuntime capability that terminates every guest process tagged with a marker, without holding any exec handle. The daemon uses it as a fallback when a detached task's supervisor died and no exec can deliver the stop request to it.

type ProxyState

type ProxyState struct {
	ProxyPath  string `json:"proxy_path"`
	GuestHost  string `json:"guest_host"`
	HostPort   int    `json:"host_port"`
	GuestPort  int    `json:"guest_port"`
	JupyterURL string `json:"jupyter_url,omitempty"`
	Token      string `json:"token,omitempty"`
	Enabled    bool   `json:"enabled,omitempty"`
	Exposed    bool   `json:"exposed,omitempty"`
}

type ProxyStateReader

type ProxyStateReader func(sandboxID string) (ProxyState, error)

ProxyStateReader fetches a sandbox's persisted ProxyState directly from the store. The k8s driver needs this because, unlike docker/microsandbox, it can't trust the proxyState an individual EnsureSandbox call happens to receive: EnsureSandbox is invoked from several call sites (guest file pushes, exec-ensure) that don't carry real jupyter config, and whichever call creates the Pod first fixes its Command forever - so the decision of whether to launch jupyter has to come from durable state, not an ad-hoc parameter. See k8sRuntime.resolveProxyState.

type RuntimeAgentEvent

type RuntimeAgentEvent struct {
	Type     string            `json:"type"`
	Message  string            `json:"message,omitempty"`
	Payload  []byte            `json:"payload,omitempty"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

type RuntimeAgentSpec

type RuntimeAgentSpec struct {
	Provider  string            `json:"provider,omitempty"`
	Model     string            `json:"model,omitempty"`
	Prompt    string            `json:"prompt,omitempty"`
	SessionID string            `json:"session_id,omitempty"`
	Metadata  map[string]string `json:"metadata,omitempty"`
}

type RuntimeCapabilityDimensionFacts

type RuntimeCapabilityDimensionFacts struct {
	Dimension       string
	Enforced        bool
	Mechanism       string
	Preconditions   []string
	Observed        string
	DefaultBehavior string
	// State is the three-state answer ("enforced", "degraded", "unsupported").
	// Empty means the reader derives it from Enforced, which keeps an API-7
	// declaration valid unchanged.
	State string
	// Source is "declared", "measured", or "simulated". A driver declaration
	// itself is declared evidence: it states what the driver writes into its
	// runtime configuration, never what it observed. Empty defaults to
	// declared.
	Source string
}

RuntimeCapabilityDimensionFacts is one dimension's raw enforcement claim.

type RuntimeCapabilityFacts

type RuntimeCapabilityFacts struct {
	// Driver is the normalized runtime driver name.
	Driver string
	// Dimensions covers every dimension pkg/capmatrix requires, exactly once.
	Dimensions []RuntimeCapabilityDimensionFacts
}

RuntimeCapabilityFacts is one runtime driver's static declaration of what it actually enforces. It is the driver-side half of the engine capability matrix; pkg/capmatrix converts these facts into the queryable contract and validates them.

The facts are deliberately a driver-local shape. pkg/llms imports pkg/driver, so pkg/driver cannot import pkg/capmatrix without creating an import cycle.

This is the static half of the engine's capability answer. The other driver-side capability shape, RuntimeInteractionCapabilities, describes what a live instance can do for one operation and is intentionally not converged into this registry; see the comment on that type for the boundary.

func CompiledRuntimeCapabilities

func CompiledRuntimeCapabilities() ([]RuntimeCapabilityFacts, error)

CompiledRuntimeCapabilities returns the capability declaration for every runtime driver compiled into this binary, in CompiledRuntimeDrivers order.

func RuntimeCapabilityFactsFor

func RuntimeCapabilityFactsFor(driver string) (RuntimeCapabilityFacts, error)

RuntimeCapabilityFactsFor returns the capability declaration for one runtime driver. It is pure: it never contacts a Docker daemon, a KVM host, or a Kubernetes cluster, so calling it for a driver that is not compiled or whose runtime is unreachable still succeeds.

type RuntimeCommandSpec

type RuntimeCommandSpec struct {
	Command string            `json:"command"`
	Args    []string          `json:"args,omitempty"`
	Env     map[string]string `json:"env,omitempty"`
	Cwd     string            `json:"cwd,omitempty"`
}

type RuntimeDriverNotCompiledError

type RuntimeDriverNotCompiledError struct {
	Driver          string
	GOOS            string
	GOARCH          string
	CompiledDrivers []string
}

RuntimeDriverNotCompiledError describes a runtime driver missing from the current binary's build capabilities.

func (*RuntimeDriverNotCompiledError) Error

func (*RuntimeDriverNotCompiledError) Unwrap

type RuntimeError

type RuntimeError struct {
	Code    string `json:"code,omitempty"`
	Message string `json:"message"`
}

type RuntimeInputFrame

type RuntimeInputFrame struct {
	Type    RuntimeInputFrameType `json:"type"`
	Data    []byte                `json:"data,omitempty"`
	Rows    uint32                `json:"rows,omitempty"`
	Cols    uint32                `json:"cols,omitempty"`
	Signal  RuntimeSignal         `json:"signal,omitempty"`
	Message string                `json:"message,omitempty"`
}

type RuntimeInputFrameType

type RuntimeInputFrameType string
const (
	RuntimeInputStdin        RuntimeInputFrameType = "stdin"
	RuntimeInputStdinEOF     RuntimeInputFrameType = "stdin_eof"
	RuntimeInputResize       RuntimeInputFrameType = "resize"
	RuntimeInputSignal       RuntimeInputFrameType = "signal"
	RuntimeInputHumanMessage RuntimeInputFrameType = "human_message"
	RuntimeInputCancel       RuntimeInputFrameType = "cancel"
)

type RuntimeInteraction

type RuntimeInteraction interface {
	Send(RuntimeInputFrame) error
	CloseSend() error
	Recv() (RuntimeOutputFrame, error)
	Wait() (RuntimeResult, error)
}

func GuardRuntimeInteractionInput

func GuardRuntimeInteractionInput(interaction RuntimeInteraction) RuntimeInteraction

GuardRuntimeInteractionInput serializes Send and CloseSend so an input pump can finish concurrently with the output loop without closing stdin twice or sending after it has been closed.

func UnsupportedRuntimeInteraction

func UnsupportedRuntimeInteraction(driver string, caps RuntimeInteractionCapabilities, spec RuntimeStartSpec) (RuntimeInteraction, error)

type RuntimeInteractionCapabilities

type RuntimeInteractionCapabilities struct {
	NativeExec    bool `json:"native_exec"`
	WrapperStream bool `json:"wrapper_stream"`
	Stdin         bool `json:"stdin"`
	StdinEOF      bool `json:"stdin_eof"`
	TTY           bool `json:"tty"`
	Resize        bool `json:"resize"`
	Signal        bool `json:"signal"`
	Artifacts     bool `json:"artifacts"`
	AgentTurns    bool `json:"agent_turns"`
}

RuntimeInteractionCapabilities describes what one live runtime instance can do for a single operation right now: stream over a wrapper, accept stdin, resize a TTY, deliver a signal. It is deliberately not part of the capmatrix isolation matrix, which answers a different question ("what does the engine enforce, by what mechanism"). This surface is instance-local and operation-local, so folding it into the static driver declarations would claim facts the engine never measured or declared. The two stay separate; callers that need an isolation decision use capmatrix, callers that need to know whether an operation is supported use this.

func (RuntimeInteractionCapabilities) ValidateStartSpec

func (c RuntimeInteractionCapabilities) ValidateStartSpec(driver string, spec RuntimeStartSpec) error

type RuntimeInteractionCapability

type RuntimeInteractionCapability string
const (
	RuntimeCapabilityNativeExec    RuntimeInteractionCapability = "native_exec"
	RuntimeCapabilityWrapperStream RuntimeInteractionCapability = "wrapper_stream"
	RuntimeCapabilityStdin         RuntimeInteractionCapability = "stdin"
	RuntimeCapabilityStdinEOF      RuntimeInteractionCapability = "stdin_eof"
	RuntimeCapabilityTTY           RuntimeInteractionCapability = "tty"
	RuntimeCapabilityResize        RuntimeInteractionCapability = "resize"
	RuntimeCapabilitySignal        RuntimeInteractionCapability = "signal"
	RuntimeCapabilityArtifacts     RuntimeInteractionCapability = "artifacts"
	RuntimeCapabilityAgentTurns    RuntimeInteractionCapability = "agent_turns"
)

type RuntimeInteractionUnsupportedError

type RuntimeInteractionUnsupportedError struct {
	Driver     string
	Operation  RuntimeOperationKind
	Capability RuntimeInteractionCapability
	Reason     string
}

func (*RuntimeInteractionUnsupportedError) Error

func (*RuntimeInteractionUnsupportedError) Unwrap

type RuntimeInteractor

type RuntimeInteractor interface {
	InteractionCapabilities() RuntimeInteractionCapabilities
	OpenInteraction(context.Context, *Sandbox, VMState, RuntimeStartSpec) (RuntimeInteraction, error)
}

type RuntimeMount

type RuntimeMount struct {
	HostPath  string `json:"hostPath"`
	GuestPath string `json:"guestPath"`
	Type      string `json:"type"`
	ReadOnly  bool   `json:"readOnly"`
}

type RuntimeMountManifest

type RuntimeMountManifest struct {
	Version int            `json:"version"`
	Driver  string         `json:"driver"`
	Mounts  []RuntimeMount `json:"mounts"`
}

func BuildRuntimeMountManifest

func BuildRuntimeMountManifest(config *appconfig.Config, session *Sandbox, driver string) (RuntimeMountManifest, error)

func LoadDirectoryRuntimeMountManifest

func LoadDirectoryRuntimeMountManifest(session *Sandbox, expectedDriver string) (RuntimeMountManifest, error)

func LoadRuntimeMountManifest

func LoadRuntimeMountManifest(session *Sandbox, expectedDriver string) (RuntimeMountManifest, error)

func PrepareRuntimeMountManifest

func PrepareRuntimeMountManifest(config *appconfig.Config, session *Sandbox, driver string) (RuntimeMountManifest, error)

type RuntimeOperationKind

type RuntimeOperationKind string
const (
	RuntimeOperationCommand RuntimeOperationKind = "command"
	RuntimeOperationAgent   RuntimeOperationKind = "agent"
)

type RuntimeOutputFrame

type RuntimeOutputFrame struct {
	Type RuntimeOutputFrameType `json:"type"`
	// Data in stdout and stderr frames is valid UTF-8 text. Runtime byte
	// streams must complete or replace invalid rune fragments before emitting.
	Data      []byte             `json:"data,omitempty"`
	Event     *RuntimeAgentEvent `json:"event,omitempty"`
	Result    *RuntimeResult     `json:"result,omitempty"`
	Error     *RuntimeError      `json:"error,omitempty"`
	StartedAt time.Time          `json:"started_at,omitempty"`
}

type RuntimeOutputFrameType

type RuntimeOutputFrameType string
const (
	RuntimeOutputStarted            RuntimeOutputFrameType = "started"
	RuntimeOutputStdout             RuntimeOutputFrameType = "stdout"
	RuntimeOutputStderr             RuntimeOutputFrameType = "stderr"
	RuntimeOutputAgentEvent         RuntimeOutputFrameType = "agent_event"
	RuntimeOutputAgentTurnCompleted RuntimeOutputFrameType = "agent_turn_completed"
	RuntimeOutputResult             RuntimeOutputFrameType = "result"
	RuntimeOutputError              RuntimeOutputFrameType = "error"
)

type RuntimeResult

type RuntimeResult struct {
	OperationID string            `json:"operation_id,omitempty"`
	ExitCode    int               `json:"exit_code"`
	Success     bool              `json:"success"`
	Error       string            `json:"error,omitempty"`
	StartedAt   time.Time         `json:"started_at,omitempty"`
	CompletedAt time.Time         `json:"completed_at,omitempty"`
	Artifacts   map[string]string `json:"artifacts,omitempty"`
	// SecurityFacts carries the lower-layer isolation failures observed during
	// this operation. It is nil when the lower layer reported nothing, so the
	// common case adds no payload.
	SecurityFacts *ExecSecurityFacts `json:"security_facts,omitempty"`
}

type RuntimeSignal

type RuntimeSignal string
const (
	RuntimeSignalInterrupt RuntimeSignal = "interrupt"
	RuntimeSignalTerminate RuntimeSignal = "terminate"
	RuntimeSignalKill      RuntimeSignal = "kill"
)

type RuntimeStartSpec

type RuntimeStartSpec struct {
	OperationID string               `json:"operation_id,omitempty"`
	Kind        RuntimeOperationKind `json:"kind"`
	Origin      string               `json:"origin,omitempty"`
	Command     *RuntimeCommandSpec  `json:"command,omitempty"`
	Agent       *RuntimeAgentSpec    `json:"agent,omitempty"`
	Cwd         string               `json:"cwd,omitempty"`
	Env         map[string]string    `json:"env,omitempty"`
	AttachStdin bool                 `json:"attach_stdin,omitempty"`
	TTY         bool                 `json:"tty,omitempty"`
	Rows        uint32               `json:"rows,omitempty"`
	Cols        uint32               `json:"cols,omitempty"`
	TimeoutMs   int64                `json:"timeout_ms,omitempty"`
	ArtifactDir string               `json:"artifact_dir,omitempty"`
}

type Sandbox

type Sandbox struct {
	Summary         SandboxSummary       `json:"summary"`
	Workspace       *SandboxWorkspace    `json:"workspace,omitempty"`
	EnvItems        []SandboxEnvVar      `json:"env_items,omitempty"`
	VolumeMounts    []SandboxVolumeMount `json:"volume_mounts,omitempty"`
	RuntimeEnvItems []SandboxEnvVar      `json:"-"`
	// NetworkPolicy is the driver-boundary egress policy the caller populated
	// from the compose declaration. A nil policy means the sandbox declared no
	// network policy, which keeps today's unrestricted behavior (D3).
	NetworkPolicy *SandboxNetworkPolicy `json:"network_policy,omitempty"`
	// ProxyEnv, when set, is invoked by a driver at the moment it builds the
	// environment of a runtime it is creating, and never when it reuses one.
	//
	// A guest reads its proxy environment once, when its runtime is created; a
	// later ensure of that same runtime cannot change it. Resolving the proxy
	// credential here, rather than when the sandbox is handed to the driver, is
	// what keeps issuance to one credential per runtime: eager resolution mints
	// a live credential on every ensure, every scheduler tick and every
	// guest-file operation, and no extra can ever be presented by a guest.
	ProxyEnv func(context.Context) ([]SandboxEnvVar, error) `json:"-"`
}

type SandboxEgressStrength

type SandboxEgressStrength string

SandboxEgressStrength is how strongly a driver enforces a declared egress policy. It is reported alongside the driver capability facts, never assumed.

const (
	// SandboxEgressStrengthNone means the driver applies no part of a declared
	// policy; egress stays as open as it is without one.
	SandboxEgressStrengthNone SandboxEgressStrength = "none"
	// SandboxEgressStrengthAllowList means the driver applies default deny plus
	// the ordered allowance list, including the engine-owned endpoints.
	SandboxEgressStrengthAllowList SandboxEgressStrength = "allowlist"
	// SandboxEgressStrengthDenyList means the driver applies an allow default
	// plus the ordered denial list, with the engine-owned endpoints ahead of it.
	SandboxEgressStrengthDenyList SandboxEgressStrength = "denylist"
)

type SandboxEnvVar

type SandboxEnvVar struct {
	Name   string `json:"name"`
	Value  string `json:"value,omitempty"`
	Secret bool   `json:"secret,omitempty"`
}

type SandboxHostConnector

type SandboxHostConnector struct {
	// contains filtered or unexported fields
}

SandboxHostConnector owns the daemon's lazily-established connection to the sandbox-host process. The connection is made on first use so a daemon whose selected driver is Docker or k8s never dials or spawns a host, and so a compose-deployed daemon simply attaches to the pre-started host.

func NewSandboxHostConnector

func NewSandboxHostConnector(socketPath, dataRoot string, mode SandboxHostMode) *SandboxHostConnector

func (*SandboxHostConnector) Client

Client returns the shared sandbox-host client, dialing and (in managed mode) spawning the host on first use. External mode only dials; it never spawns.

func (*SandboxHostConnector) Close

func (c *SandboxHostConnector) Close() error

Close closes the shared transport, if any. It is safe to call more than once.

func (*SandboxHostConnector) ProtocolVersion

func (c *SandboxHostConnector) ProtocolVersion() int64

ProtocolVersion reports the protocol version negotiated with the sandbox-host during the last successful dial. It is zero until the host is first reached, which matches "no deny support" for a host the daemon has never spoken to.

The version is negotiated once per daemon lifetime, at first dial: the daemon and host are the same binary, so a host upgrade is what changes the version, and the daemon re-negotiates it when it next starts (the #805 flow upgrades the daemon, which restarts and re-dials). A host upgraded in place under a running daemon keeps the daemon's cached version until the daemon restarts; because capability gating (see requireDenyProtocolVersion) fails closed on a stale version, that is safe, only conservative.

type SandboxHostMode

type SandboxHostMode string

SandboxHostMode controls whether the daemon may spawn the sandbox-host process itself or must only attach to one that is managed outside it.

const (
	// SandboxHostModeExternal means the host is managed outside the daemon
	// (for example by Docker Compose) and the daemon must only dial it, never
	// spawn it. Spawning here would create an unprivileged host without
	// /dev/kvm inside the daemon's container, which could steal the data-root
	// lock from the real host and put it into a restart loop.
	SandboxHostModeExternal SandboxHostMode = "external"
	// SandboxHostModeManaged means the daemon may spawn the host on first use.
	// It is intended for local development and native deployments.
	SandboxHostModeManaged SandboxHostMode = "managed"
)

type SandboxNeedsCreate

type SandboxNeedsCreate interface {
	NeedsCreate(context.Context, *Sandbox, VMState) (bool, error)
}

SandboxNeedsCreate is an optional SandboxRuntime capability the sandbox-host uses to split ensure into two phases. It reports whether the sandbox's runtime does not yet exist — or has gone stale and must be rebuilt — so the daemon can resolve create-time credentials (ProxyEnv) only when a runtime will actually be created rather than on every ensure. Implementations may connect to the runtime (and clean up a stale handle) to answer reliably.

type SandboxNetworkEnforcement

type SandboxNetworkEnforcement struct {
	Driver    string
	Strength  SandboxEgressStrength
	Mechanism string
	// AppliesAllowEntries reports whether declared allowances reach the driver.
	AppliesAllowEntries bool
	// AppliesDenyEntries reports whether declared denials reach the driver.
	AppliesDenyEntries bool
	// AppliesEngineEndpoints reports whether the engine-owned endpoints stay
	// reachable when the policy restricts.
	AppliesEngineEndpoints bool
	// AppliesDenyDomains reports whether the declared deny domains reach the
	// driver's DNS resolution path.
	AppliesDenyDomains bool
	// AppliesAllowedAddresses reports whether this mechanism can constrain which
	// addresses a declared name may resolve to. Only a mediator that resolves the
	// destination itself can, so a driver that pushes host patterns to a runtime
	// leaves that part of a declaration unapplied rather than applying it
	// partially without saying so.
	AppliesAllowedAddresses bool
	// Notes is the human-readable limit of what the driver applies, so a report
	// never presents a partial mechanism as complete.
	Notes string
}

SandboxNetworkEnforcement describes one runtime driver's egress enforcement.

func SandboxEgressForwardProxyEnforcement

func SandboxEgressForwardProxyEnforcement(driver string) SandboxNetworkEnforcement

SandboxEgressForwardProxyEnforcement is the enforcement a sandbox gains from the engine's own forward proxy rather than from its driver. The decision is the engine's and it applies the declared allowances, denials, and engine-owned endpoints, so the strength is an allowlist or denylist on every driver whose guest reaches the daemon.

The limit is the transport: a process that ignores the proxy environment dials the internet directly and is not decided, until transparent capture puts every connection through the proxy. The note says so rather than implying the declaration covers traffic the proxy never saw.

func SandboxNetworkEnforcementFor

func SandboxNetworkEnforcementFor(driver string) SandboxNetworkEnforcement

SandboxNetworkEnforcementFor returns the enforcement declaration for one runtime driver. It is pure and never probes a runtime.

type SandboxNetworkPolicy

type SandboxNetworkPolicy struct {
	Default egress.Action
	// Allow is the declared allowance list in declaration order. Order does not
	// change the outcome because every entry allows, but it is preserved so a
	// report can echo the declaration. It is the declaration layer's own entry
	// type rather than a narrowed endpoint so an entry's allowed address range
	// survives the seam: a boundary policy that quietly dropped a constraint
	// would let a driver enforce less than the project declared.
	Allow []egress.AllowEntry
	// Deny is the declared refusal list in declaration order. A denial wins over
	// an allowance that matches the same destination.
	Deny []egress.DenyEntry
	// EngineEndpoints are the engine-owned endpoints that must stay reachable
	// whenever the policy restricts.
	EngineEndpoints []egress.EngineEndpoint
	// DenyDomains are exact domain names the driver refuses to resolve. The
	// compose declaration does not carry them yet, so they are engine-supplied.
	DenyDomains []string
	// MediatedByForwardProxy reports that the engine, not the driver, decides
	// this sandbox's egress: the guest was given the engine's forward proxy as
	// its egress path, so the declaration is enforced on a driver that has no
	// enforcement surface of its own.
	//
	// It is set by the caller that actually routed the guest through the proxy,
	// in the same step that added the proxy environment, so a driver can never
	// believe in a mediation the engine did not wire. A driver reads it only to
	// report enforcement honestly and to skip the unenforced-declaration gate.
	MediatedByForwardProxy bool
}

SandboxNetworkPolicy is the driver-boundary network policy for one sandbox.

Default is egress.Allow for an undeclared policy (D3): the zero value is not default-deny. Allow holds the declared allowances, Deny holds the declared refusals, and EngineEndpoints holds the engine-owned endpoints the engine derives from its own configuration (LLM facade, telemetry). Engine endpoints precede every declared rule whenever the policy restricts, so no user declaration can deny them, and they are never hardcoded here — the caller supplies them.

func NewSandboxNetworkPolicy

func NewSandboxNetworkPolicy(defaultAction egress.Action, allow []egress.AllowEntry, deny []egress.DenyEntry, engineEndpoints []egress.EngineEndpoint, denyDomains []string) (SandboxNetworkPolicy, error)

NewSandboxNetworkPolicy normalizes and validates a boundary policy. It returns an error for a value a driver could not enforce, so a malformed declaration fails closed instead of silently widening access.

func SandboxNetworkPolicyFromDeclaration

func SandboxNetworkPolicyFromDeclaration(declaration *egress.NetworkDeclaration, engineEndpoints []egress.EngineEndpoint, denyDomains []string) (SandboxNetworkPolicy, error)

SandboxNetworkPolicyFromDeclaration is the explicit seam between the compose declaration layer and the drivers. It converts the declaration layer's normalized network declaration plus the engine-owned endpoints into the driver-boundary policy.

A nil declaration means no policy was declared, so the result permits all egress (D3); the engine-owned endpoints are then irrelevant because nothing is denied.

func (SandboxNetworkPolicy) AddressConstrainedAllowances

func (p SandboxNetworkPolicy) AddressConstrainedAllowances() int

AddressConstrainedAllowances counts the declared allowances that constrain which addresses a name may resolve to. A mechanism that applies the destinations but not these ranges is applying less than the project declared, so it has to say so rather than run as if the constraint were in place.

func (SandboxNetworkPolicy) DenyByDefault

func (p SandboxNetworkPolicy) DenyByDefault() bool

DenyByDefault reports whether the policy refuses unmatched destinations. An unrepresentable default is treated as deny so an invalid policy can never widen access.

func (SandboxNetworkPolicy) Restricts

func (p SandboxNetworkPolicy) Restricts() bool

Restricts reports whether the policy can refuse any destination: a deny default, or at least one declared denial. An allow default with no denial cannot narrow egress, which is the legacy behavior of an allow list without default: deny-all.

func (SandboxNetworkPolicy) Validate

func (p SandboxNetworkPolicy) Validate() error

Validate rejects a policy a driver could not enforce. The destinations and protocols are validated by pkg/egress, so the boundary type cannot accept a value the decision model would reject.

type SandboxRuntime

func NewBoxliteRuntime

func NewBoxliteRuntime(config *appconfig.Config) (SandboxRuntime, error)

func NewDockerRuntime

func NewDockerRuntime(config *appconfig.Config) (SandboxRuntime, error)

func NewK8sRuntime

func NewK8sRuntime(config *appconfig.Config, proxyStateReader ProxyStateReader) (SandboxRuntime, error)

func NewMicrosandboxRuntime

func NewMicrosandboxRuntime(config *appconfig.Config) (SandboxRuntime, error)

func NewRemoteSandboxRuntime

func NewRemoteSandboxRuntime(driver string, connector *SandboxHostConnector) SandboxRuntime

NewRemoteSandboxRuntime returns a SandboxRuntime that proxies the named VM driver to the sandbox-host process behind connector. It implements the full SandboxRuntime surface plus the optional Stats, IsSandboxAlive, SignalGuestRuntime, TerminateProcessTree, and RuntimeInteractor interfaces.

type SandboxStartTarget

type SandboxStartTarget struct {
	Driver  string
	Session *Sandbox
	VMState VMState
}

SandboxStartTarget identifies the sandbox and runtime driver to prepare for start.

type SandboxStats

type SandboxStats struct {
	SandboxID        string
	Driver           string
	SampledAt        time.Time
	CPUPercent       MetricValue
	MemoryUsageBytes MetricValue
	MemoryLimitBytes MetricValue
	MemoryPercent    MetricValue
	NetworkRxBytes   MetricValue
	NetworkTxBytes   MetricValue
	BlockReadBytes   MetricValue
	BlockWriteBytes  MetricValue
	UptimeSeconds    MetricValue
}

type SandboxSummary

type SandboxSummary struct {
	ID            string    `json:"id"`
	Driver        string    `json:"driver"`
	GuestImage    string    `json:"guest_image,omitempty"`
	PullPolicy    string    `json:"pull_policy,omitempty"`
	RuntimeRef    string    `json:"runtime_ref,omitempty"`
	WorkspacePath string    `json:"workspace_path"`
	CreatedAt     time.Time `json:"created_at"`
	UpdatedAt     time.Time `json:"updated_at"`
}

type SandboxVMInfo

type SandboxVMInfo struct {
	BoxID      string
	JupyterURL string
	ProxyState *ProxyState
	// RuntimeCreated reports that this call created the runtime rather than
	// reusing one that already existed. The engine asks a start to *ensure* a
	// runtime, so this is the only fact that distinguishes "built under the
	// configuration resolved now" from "started again with the one it already
	// had". A driver that does not report it leaves the engine unable to tell,
	// and callers must treat false as unknown rather than as reuse.
	RuntimeCreated bool
}

type SandboxVolumeMount

type SandboxVolumeMount struct {
	ID       string `json:"id,omitempty"`
	Type     string `json:"type"`
	Source   string `json:"source"`
	Target   string `json:"target"`
	ReadOnly bool   `json:"read_only,omitempty"`
	VolumeID string `json:"volume_id,omitempty"`
	Driver   string `json:"driver,omitempty"`
	HostPath string `json:"host_path"`
}

type SandboxWorkspace

type SandboxWorkspace struct {
	Type       string `json:"type"`
	ConfigJSON string `json:"config_json"`
}

SandboxWorkspace carries the persisted delivery contract into the runtime boundary.

type StdioStream

type StdioStream string
const (
	StdioStdout StdioStream = "stdout"
	StdioStderr StdioStream = "stderr"
)

func NormalizeStdioStream

func NormalizeStdioStream(stream StdioStream) StdioStream

type VMState

type VMState struct {
	Driver           string    `json:"driver"`
	Mode             string    `json:"mode,omitempty"`
	BoxName          string    `json:"box_name,omitempty"`
	BoxID            string    `json:"box_id,omitempty"`
	Image            string    `json:"image,omitempty"`
	Registry         string    `json:"registry,omitempty"`
	RuntimeHome      string    `json:"runtime_home,omitempty"`
	StartedAt        time.Time `json:"started_at,omitempty"`
	StartAttemptedAt time.Time `json:"start_attempted_at,omitempty"`
	StoppedAt        time.Time `json:"stopped_at,omitempty"`
	LastError        string    `json:"last_error,omitempty"`
	BootstrapRef     string    `json:"bootstrap_ref,omitempty"`
	// K8sContext and K8sNamespace override which cluster/namespace the k8s
	// driver targets for this sandbox. Empty means "use the daemon's
	// K8S_KUBECONFIG current-context / K8S_NAMESPACE default" (see
	// k8sRuntime.client and k8sRuntime.namespaceFor). Other drivers ignore
	// these fields.
	K8sContext   string `json:"k8s_context,omitempty"`
	K8sNamespace string `json:"k8s_namespace,omitempty"`
}

func PrepareSandboxStart

func PrepareSandboxStart(ctx context.Context, config *appconfig.Config, target SandboxStartTarget) (VMState, error)

Source Files

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL