15 KiB
Lazaret Specification
This document is the normative product specification for Lazaret. It defines the problem, stable vocabulary, architecture, and requirements. The TLA+ application protocol model defines lifecycle and communication semantics. The implementation plan records current technology choices, configuration schema, sequencing, and validation work. Experimental results and historical rationale belong in the journal.
1. Problem Statement
AI coding agents need broad local capabilities: they run arbitrary tools, modify a project, use Git, install dependencies, and access selected network services. Code produced or invoked by an agent is not trusted to run directly on the developer's host. A conventional container reduces risk, but poor terminal behavior, transient tool state, restricted Git access, and manual setup can make the safe path too inconvenient for routine work.
Lazaret's north star is:
Make isolated agent execution the easiest way to work, while ensuring that every transition from the sandbox to host authority is explicit, attributable, and controlled by the developer.
Lazaret therefore provides a rootless gVisor sandbox with a bidirectionally shared workspace, persistent sandbox-local tooling, controlled network egress, and a human-in-the-loop host escalation path.
1.1 Trust Model
The following components are trusted:
- The developer and host operating system.
- The Lazaret CLI and the domain's Session Coordinator.
- Host configuration selected by the developer.
- The Network Sidecar and the policy given to it by Lazaret.
The following components are untrusted:
- The agent and every process it launches.
- Code, tools, and package installation scripts executed inside the Agent Sandbox.
- Data received from the network by sandboxed processes.
All Client Sessions in the same Domain intentionally share an Agent Sandbox and are one sandbox trust domain. Session identity distinguishes ownership and routes terminal interactions; it is not an isolation boundary between processes in that sandbox.
The Agent Workspace is intentionally writable. Lazaret protects the host outside the explicitly mounted workspace and volumes; it does not protect workspace files from modification or deletion by the agent.
Host configuration is read only by host Lazaret processes. A configuration file must not be mounted into, or located beneath a host path mounted into, the Agent Sandbox.
2. Glossary
These terms and identifiers are stable across the specification, protocol model, implementation plan, logs, and user interfaces.
| Term | Definition |
|---|---|
| Agent Profile | A developer-selected host configuration describing an agent image and its granted storage, network, environment, and escalation capabilities. |
| Agent Workspace | The canonical host project directory mounted read-write at /workspace in the Agent Sandbox. |
| Agent Sandbox | The rootless gVisor container in which an agent and its child processes execute. One sandbox is shared by all Client Sessions in a Domain. |
| Agent Sandbox ID | A runtime-unique identifier assigned to one Agent Sandbox instance and bound to its Domain protocol identity. |
| Client Session | One active host Lazaret CLI process and the interactive or non-interactive command it attaches to the Agent Sandbox. |
| Session ID | A cryptographically random identifier unique to one Client Session. |
| Session Anchor | Ephemeral session credentials that bind protocol messages to a registered Session ID and route them to the owning host CLI. |
| Session Coordinator | The ephemeral host process that exclusively owns and coordinates a Domain's runtime resources and Client Sessions. |
| Domain | The shared runtime and persistent-state scope for one (Agent Profile, canonical Agent Workspace) pair. |
| Domain ID | A deterministic identifier derived from the Agent Profile name and canonical Agent Workspace path. It namespaces Domain resources but is not an authentication credential. |
| Domain Root | The host-only directory containing persistent state and metadata for one Domain. |
| Network Sidecar | The trusted, shell-less gateway container that establishes the Domain's network policy before the Agent Sandbox starts. |
| Network Sidecar ID | A runtime-unique identifier assigned to the Network Sidecar instance owned by a Domain. |
| Git Sentry | The protective mount layout that preserves bidirectional workspace and Git access while preventing writes to the host's default Git hooks and repository configuration. |
| State Anchor | The Domain-scoped persistent writable filesystem layer merged over selected paths from the sandbox base image. |
| Trust Anchor | The ephemeral Domain-scoped certificate authority used to authenticate Lazaret protocol peers. |
| Escalation Client | The Lazaret-provided executable through which a sandboxed process requests a host action. |
| Escalation Request ID | A cryptographically random identifier used to correlate one host escalation request and response. |
| Host Escalation | A request by a sandboxed process for Lazaret to execute a developer-approved or auto-approved action with host authority. |
| Configuration Fingerprint | A cryptographic digest of the validated host configuration that created or joined a running Domain. |
| Storage Root | The trusted host directory beneath which Lazaret stores Domain Roots and profile-scoped state. |
3. Architecture
3.1 System Boundaries
flowchart LR
subgraph Host[Trusted host]
CLI[Client CLI]
Config[Host configuration]
HostWorkspace[Agent Workspace]
Coordinator[Session Coordinator]
State[State Anchor]
Gateway[Network Sidecar]
HostExec[Approved host process]
end
subgraph Sandbox[Untrusted Agent Sandbox - rootless runsc]
Agent[Agent and child processes]
Workspace[/workspace mount]
Escalate[Escalation Client]
end
Config --> CLI
HostWorkspace <--> Workspace
CLI <--> Coordinator
Coordinator --> State
Coordinator --> Gateway
Coordinator --> Agent
Agent <--> Workspace
Agent --> Escalate
Escalate --> Coordinator
Coordinator --> HostExec
Agent --> Gateway
Gateway --> Network[Permitted destinations]
The Agent Sandbox uses gVisor's application-kernel isolation under rootless Podman. Rootless operation limits the host authority of the runtime, while gVisor interposes a separate userspace kernel between untrusted processes and the host kernel. The Network Sidecar is a separate trusted component and is not part of the untrusted agent environment.
3.2 Domain and Session Lifecycle
The Session Coordinator is the single owner of a Domain's Agent Sandbox, Network Sidecar, State Anchor, sockets, and active-session registry. Concurrent CLI processes for the same Domain join the existing coordinator and attach separate Client Sessions to the shared sandbox. Different Domains never share these resources.
The first Client Session starts the Domain. The coordinator prepares persistent state, establishes network policy, starts the Agent Sandbox, and then accepts the session. When no Client Sessions remain, it tears down transient resources while retaining Domain-scoped persistent state.
Startup, registration, cancellation, recovery, and teardown transitions are defined by the TLA+ application protocol model.
3.3 Filesystem and Git Model
The Agent Workspace is mounted read-write and changes propagate in both
directions. Workspace content, the Git index, HEAD, references, and objects are
therefore shared with the host in real time. Lazaret does not create a separate
worktree or branch and does not promise that the host working tree remains
unchanged.
Lazaret applies narrow protective mounts over host integration files that must not be modified by the agent:
- The host repository's
.git/configis exposed read-only. - The host repository's
.git/hooksis hidden behind sandbox-local transient storage. - Supported host editor configuration directories may be hidden behind sandbox-local transient storage.
These protections do not make the workspace immutable. Their purpose is to stop the sandbox from writing the protected host Git configuration and default hook directory while preserving normal Git operations and bidirectional source edits.
3.4 Persistent Sandbox State
The State Anchor preserves developer tooling and selected sandbox system paths for one Domain. It combines a read-only lower directory from the selected base image with a Domain-scoped writable upper directory.
Files not represented in the upper layer follow the selected base image. Files, directories, and whiteouts recorded in the upper layer remain authoritative when the lower image changes. This permits installed tools to survive restarts while allowing unmodified base-image content to follow the selected image.
Persistent state is sandbox state, not host configuration. It must not contain or override Lazaret's host control plane.
3.5 Network Isolation
The Network Sidecar establishes the Domain's egress routes before the Agent Sandbox starts. The sidecar alone receives the network-administration capability needed to install policy; the Agent Sandbox does not receive that capability.
Network policy is expressed as permitted and denied destination prefixes. Normal Linux longest-prefix routing determines the most specific matching route; an equal-prefix conflict must be rejected or resolved in favor of denial. IPv4 and IPv6 must either receive equivalent policy or an address family must be disabled.
The topology and policy-installation sequence must ensure that all external Agent Sandbox traffic traverses the configured enforcement path. Dynamic policy changes are not a requirement unless the implementation can apply them without weakening that property.
3.6 Host Escalation
The Escalation Client communicates with the Session Coordinator over a Domain-scoped host-private Unix socket. The Trust Anchor authenticates the Domain peer, and the Session Anchor binds the request to a registered Client Session. A verified request is routed only to that session's host CLI.
A host command may run only when the developer approves it interactively or when it matches an auto-approval rule in trusted host configuration. Auto-approved commands are launched directly as an argument vector without a shell. Rules match the complete vector by default; permission for arbitrary trailing arguments is an explicit property of an individual rule.
Interactive approval may allow the developer to approve, deny, or edit a request. The request must reach a terminal state and terminal ownership must return to the sandbox session after resolution.
Authentication, message correlation, approval, execution, cancellation, and terminal-routing transitions are defined by the TLA+ application protocol model.
4. Requirements
4.1 Security Requirements
| ID | Requirement |
|---|---|
| SR-1 | Agent processes shall execute in a rootless gVisor sandbox and shall not receive host root authority. |
| SR-2 | Host configuration shall never be mounted into the Agent Sandbox or located beneath a host path mounted into it. |
| SR-3 | Host paths outside the Agent Workspace and developer-configured volumes shall not be accessible to the Agent Sandbox. |
| SR-4 | The sandbox shall be unable to modify the host repository's .git/config or default .git/hooks directory through the workspace mount. |
| SR-5 | The Network Sidecar shall establish network policy before the Agent Sandbox starts, and the Agent Sandbox shall not receive network-administration capability. |
| SR-6 | Network policy shall cover every enabled address family and shall deny equal-specificity policy conflicts. |
| SR-7 | A host action shall execute only after interactive developer approval or a match against a trusted host auto-approval rule. |
| SR-8 | Auto-approved host commands shall execute without a shell and shall permit trailing arguments only when the matched rule explicitly grants them. |
| SR-9 | Escalation requests shall be authenticated to a Domain and bound to a registered Session ID before routing or execution. |
| SR-10 | Domain sockets and coordination files shall reside in a host-private directory owned by the developer. |
| SR-11 | Runtime and persistent resources belonging to different Domain IDs shall remain isolated. |
4.2 Functional Requirements
| ID | Requirement |
|---|---|
| FR-1 | Lazaret shall derive a stable Domain ID from the selected Agent Profile and canonical Agent Workspace. |
| FR-2 | Concurrent Client Sessions in one Domain shall share one coordinator, Agent Sandbox, Network Sidecar, and State Anchor. |
| FR-3 | Workspace edits and supported Git operations shall propagate bidirectionally between host and sandbox. |
| FR-4 | Selected sandbox paths shall persist across Domain restarts without copying Lazaret host configuration into the sandbox. |
| FR-5 | The coordinator shall route an escalation prompt and response to the Client Session identified by the verified Session ID. |
| FR-6 | The final Client Session leaving a Domain shall trigger teardown of transient Domain resources. |
| FR-7 | Startup and teardown shall recover safely from interrupted or stale prior executions. |
| FR-8 | Lazaret shall support interactive terminal sessions without degrading supported host terminal capabilities. |
4.3 Developer-Experience Requirements
| ID | Requirement |
|---|---|
| DX-1 | A developer shall be able to launch an Agent Profile in the current workspace with one command. |
| DX-2 | Tools installed in configured persistent sandbox paths shall remain available on later launches of the same Domain. |
| DX-3 | Normal source editing, git status, staging, committing, and reference updates shall work from inside the Agent Sandbox. |
| DX-4 | Escalation prompts shall identify the requesting profile, session, command, and justification without mixing terminal input or output between sessions. |
| DX-5 | Failures shall report actionable diagnostics and shall not leave the developer's terminal in a corrupted mode. |
4.4 Operational Requirements
| ID | Requirement |
|---|---|
| OR-1 | The coordinator shall maintain exclusive runtime ownership of Domain resources. |
| OR-2 | Every protocol request shall resolve to a completed, denied, timed-out, cancelled, or failed state. |
| OR-3 | Cancellation and process termination shall not strand an active host command or permanently block another Client Session. |
| OR-4 | Security-sensitive behavior shall be covered by integration tests on supported Podman, runsc, filesystem, and network configurations. Test evidence belongs in the journal. |