Package Installation Workflows in Persistent Agent VMs
How persistent VMs require layered policies to manage dependencies that survive across sessions.

Firecracker microVM isolation gives each AI agent its own guest kernel, while containers share the host kernel. In a persistent agent VM, package installation becomes a stateful workflow because dependencies and install-time changes survive across sessions. The VM boundary limits the reach of a compromised install, but reliable operation still requires environment layering, explicit persistence rules, scoped privileges, and install-hook controls.
Why package installation in a persistent agent VM is a different problem than in a stateless environment
With stateless execution, the image is the main place to manage dependencies. When an ephemeral environment is destroyed, its local install side effects disappear with it. A persistent VM changes that contract. Installed packages, modified configuration files, and transitive dependencies can survive sleep, wake, and redeploy, making a decision from session one an environmental fact in session forty.
GrokBot and Muse both provide a dedicated per-user VM shared across that user’s Bots, with filesystem and terminal access. A successful install is no longer sufficient evidence that an environment is ready for reuse, because its effects may outlast the task that required it.
How Firecracker microVM isolation gives each AI agent its own kernel and changes the blast radius
Firecracker runs one virtual machine monitor process for each microVM, which has its own guest kernel. The guest runs behind a hardware virtualization boundary, while containers share a host kernel. Intel VT-x separates VMX root and VMX non-root execution, while AMD-V provides the corresponding SVM separation. Guest code cannot directly access host memory or host kernel interfaces. Compromising a guest kernel does not by itself grant control of the host kernel or neighboring VMs.
That boundary changes which installation risks are tractable. An unexpected package can damage the guest without also gaining the same control over other workloads. It does not make installation safe by default. Assessing isolation still requires checking the jailer and device surface, and hooks and transitive dependencies still run with the privileges they have inside the guest.
Snapshot-restore provides the other essential mechanism for persistent install workflows. A VM can be frozen mid-session and restored in tens of milliseconds, preserving an installed environment as a reusable starting point. Memory copy-on-write supports cheap branching from that state. Disk branching requires external copy-on-write tooling, such as reflinking, rather than an assumption that stock Firecracker supplies disk layering. With both in place, speculative installs can run in separate branches without polluting one another.
Environment layering — separating the base snapshot from the session layer from the task layer
The base snapshot contains the OS, runtimes, and common tooling installed at image-authoring time. These installs happen once, receive review, and become the starting environment for sessions spawned from the template. Without that work, an agent that lacks Python or Node has to install its own tools at the start of each session. Dependency resolution becomes a recurring failure point. Docker Sandboxes illustrates the alternative by pre-installing Docker CLI, Git, GitHub CLI, Node.js, Python 3, Go, ripgrep, and jq.
The session layer contains packages installed for the current work without changing the base. A read-only root filesystem with only a scoped workspace directory writable provides a structural boundary for those changes. The task layer has a shorter lifetime. It holds speculative dependencies for a single subtask, ideally in a copy-on-write branch that can be discarded independently of the session. Each layer therefore has its own authorship, lifetime, and rollback rules.
Published benchmarks show that end-to-end creation from a snapshot takes approximately 203ms p99, which measures more than the time to restore VM state alone. Prepared environments can therefore be the normal starting point. The expensive work of resolving common dependencies belongs in snapshot authoring, while session and task layers accommodate the dependencies that cannot be known in advance.
Dependency persistence across snapshots — what survives, what should not, and how to control the difference
A snapshot preserves state without deciding whether that state deserves to survive. Packages installed through pip install or npm install remain in the writable layer and can pass into later sessions unless policy removes them. A dependency installed for one task can conflict with another task’s requirements several sessions later and cause a runtime error far from the original decision.
Persistence also extends the consequences of a malicious install. A hook may run only once, but the files and configuration it changed can remain in every later restore. Restoring that snapshot is not a clean recovery. Rollback cannot take back environment variables that were already exfiltrated, and tainted local state has to be rebuilt from a clean base.
The corresponding policy should make session layers disposable by default and require explicit promotion into the base snapshot. A scoped writable workspace limits where packages can land, but it does not decide how long they remain. Eviction rules supply that missing decision. They should name which layers are rebuilt at session start and which are retained, with a TTL or promotion gate preventing unreviewed dependencies from becoming permanent by accident.
Privilege scope during install — why full root inside the VM is not the same as full root on the host
Root inside a Firecracker guest gives an agent control over that guest’s packages, configuration, and processes. It does not confer host root privileges. Guest root still runs within VMX non-root execution on Intel, so even with higher guest privileges, reaching beyond the VM requires breaking through the isolation boundary. This makes permissive installation defensible for some workflows. It does not protect the guest’s own files or credentials from an installer with unrestricted access.
Meta’s Muse architecture illustrates one placement of the privilege boundary. Its agent runtime runs inside a systemd-nspawn container where root maps to an unprivileged host user, with an isolated root filesystem. GrokBot illustrates a different boundary choice through a per-user shared VM. Firecracker keeps users apart, but bots in the same account share files and command-line credentials, so xAI’s documentation warns against putting credentials there if other bots should not have access to them.
Installation authority should match the narrowest required capability. Installing into a scoped directory does not require the same authority as changing the entire guest OS. These are distinct operating modes. Package-manager restrictions can reinforce VM isolation, while permissive “install freely” modes trade stronger internal controls for the ability to install, break, and rebuild within the guest. A read-only-root session should not silently become that unrestricted mode.
Install-hook safety — the specific risk that stateless systems never had to design for
Install hooks are executable code. In an ephemeral environment, a malicious hook can steal information it can reach before the environment is destroyed and its local changes are removed. Credentials, cached tokens, open browser sessions, and accumulated files provide a richer target, while changed configuration can survive into later snapshots.
A proxied registry mirror can block packages whose hooks are known to be malicious or remove those hooks before the packages are installed. That puts enforcement outside the agent’s judgment. A stricter no-network mode disables outbound access during installation and requires dependencies to exist in a pre-seeded local cache or registry. The agent can still choose packages without being able to reach arbitrary endpoints during install-time execution. These modes address different network requirements and should not be treated as interchangeable.
Hooks can run in a further-isolated subprocess or a disposable nested VM branch, with installed package files promoted into the session layer only after a clean exit. The operational value of successful execution, with benign behavior still unproven, is that the install runs outside the durable session until promotion, so a failed attempt need not leave its changes behind.
Routing install commands through the right dispatch layer — CLI vs. MCP and why the split matters for agents
A known install command belongs at the CLI layer. Commands such as pip install requests and npm install lodash can live in a human-reviewed script or Makefile when the dependency choice is known at authoring time. The command executes an already-made decision. By contrast, an agent that reads a codebase and selects a library during a task is making that decision at runtime. An MCP server exposes the installation capability as a tool for that dispatch.
Building the CLI first and placing MCP above it preserves a common enforcement path. The command that humans use and the tool that agents use can share the same registry restrictions, privilege scope, and hook isolation. The entry point must not change the policy. Otherwise, an install allowed through one interface may skip controls in the other, leaving a gap in the audit just where the agent starts choosing packages on its own.
For coding tasks, the practical configuration is read-write access to a scoped workspace, no network by default, and package installation allowed only through a proxied registry mirror. The mirror is a controlled exception to the outbound-access restriction. Infrastructure enforces those constraints regardless of whether a human invokes the CLI or an agent invokes the MCP tool. The dispatch layer decides what to request, while the installation layer governs what can execute.
Snapshot-restore as the economic and operational backbone of the install workflow
When an agent becomes idle, snapshot-restore freezes its working directory, dependencies, processes, and warm page cache for later restoration. Nothing runs during that parked interval. With nothing running, the ongoing cost shifts toward storage rather than vCPU time, so a fully installed environment for each agent can be affordable even when the agent is not always active.
This cost model strengthens the case for a prepared base snapshot. Rebuilding common tooling every session spends active time reconstructing an environment that could already exist. Snapshot authoring moves that work out of repeated execution. Restoring it makes the prepared environment ready for bursts of work without keeping it running between them. The optimization target shifts from repeatedly minimizing setup work to authoring a useful baseline and controlling its later mutations.
The distinction between necessary dependencies and uncontrolled accumulation remains important. Paying for storage while an agent is idle is no reason to keep every package it has ever tried. Layering serves both concerns at once. The base keeps reviewed dependencies, the session keeps working state that is explicitly allowed, and throwing away task branches keeps experiments from taking up storage for good. Low restore latency makes per-invocation creation from a snapshot practical, with a true cold boot needed only for the template’s first spawn.
What a production-grade install workflow looks like end to end
Implementation should begin with a human-authored, CI-gated template VM. Its base includes Python, Node, Go, common tools such as Git, uv, and jq, and the domain-specific packages needed for most tasks. Promotion is a separate gate. The build pipeline verifies that the snapshot boots cleanly and passes a dependency audit before it becomes the starting point for production sessions.
A session then restores that base with a read-only root filesystem and a scoped writable workspace. Task-specific packages enter the workspace through the controlled installation interface, where the registry mirror enforces the allowed package set and strips known-bad hooks. Runtime-selected packages take a more cautious path. The MCP install tool dispatches them by default into a copy-on-write branch of the current session, where installation and the task run before the result is promoted or discarded.
When the agent parks, the permitted session state is frozen to disk without keeping active compute running. Idle preservation does not grant indefinite retention. Session packages survive through explicit promotion or until their TTL expires, while packages not promoted are evicted at session end or after the defined period. Reusable dependencies return to base authoring and its review process rather than entering the template through an agent’s incidental success.
The VS Code Agent Host architecture illustrates the same lifetime separation at the tooling layer. A self-contained process owns agent sessions independently of individual editor windows, so persistent context does not belong to a transient interface. Installation needs that same independence from the command that initiated it. The production unit is the governed environment, with explicit rules for creation, mutation, restoration, promotion, and disposal.


