264 lines
15 KiB
Markdown
264 lines
15 KiB
Markdown
# 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](protocol/Lazaret.tla) defines lifecycle and communication
|
|
semantics. The [implementation plan](implementation-plan.md) records current
|
|
technology choices, configuration schema, sequencing, and validation work.
|
|
Experimental results and historical rationale belong in the [journal](journal.md).
|
|
|
|
## 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
|
|
|
|
```mermaid
|
|
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](protocol/Lazaret.tla).
|
|
|
|
### 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/config` is exposed read-only.
|
|
- The host repository's `.git/hooks` is 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](protocol/Lazaret.tla).
|
|
|
|
## 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. |
|