Persistent workspaces
Persistent state is useful for agents, browser sessions, caches, databases, and long-running services. It is also where sensitive data accumulates. Choose the smallest state mechanism that fits the workflow, and make the retention policy explicit before the sandbox starts.
Pick a state mechanism
Section titled “Pick a state mechanism”| Need | Use | Security posture |
|---|---|---|
| One input file or result file | mvmctl cp or mvmctl fs | Narrowest boundary; preferred for generated-code tasks. |
| Read-only fixtures | mvmctl run --add-dir ...:ro | Host data is exposed but not writable by the guest. |
| Local dev edits | mvmctl run --profile dev --add-dir ...:rw | Writable host share; use only for trusted dev workflows. |
| Stateful app data | managed encrypted volume | Encrypted at rest when locked; plaintext exists while unlocked. |
| Fast retry or recovery | snapshot or cold mode | Can contain memory, files, processes, prompts, and credentials. |
Do not use a snapshot when a narrow output file is enough. Do not use a writable host share when a managed volume is enough.
Managed encrypted volume
Section titled “Managed encrypted volume”Create a managed local volume:
mvmctl volume create agent-cacheManaged volumes are locked by default. Unlock before mounting:
mvmctl volume unlock agent-cacheMount the unlocked volume into a running sandbox:
mvmctl volume mount agent-sandbox \ --volume agent-cache \ --guest /cache \ --rwList mounts:
mvmctl volume ls agent-sandboxUnmount and lock when the workflow is done:
mvmctl volume unmount agent-sandbox /cachemvmctl volume lock agent-cacheSecurity rules:
volume mountrefuses a managed volume while it is locked;volume unlockcreates plaintext state that must be treated as sensitive;volume lockreseals the volume and removes plaintext after use;- keep volume names scoped to the workflow or project;
- do not mount the same writable volume into unrelated sandboxes unless sharing state is the intent.
Host-backed mounts
Section titled “Host-backed mounts”Ad-hoc host-backed mounts are useful when an existing encrypted host directory is the source of truth:
mvmctl volume mount agent-sandbox \ --volume project-data \ --host /absolute/path/to/data \ --guest /dataUse --rw only for trusted workflows:
mvmctl volume mount agent-sandbox \ --volume project-data \ --host /absolute/path/to/data \ --guest /data \ --rwThe host directory must live on encrypted backing storage. If encryption cannot be verified, the command should fail closed.
Copy instead of mount
Section titled “Copy instead of mount”For model-generated code, third-party scripts, and code interpreter workloads, prefer copy-in/copy-out:
mvmctl cp ./input.json agent-sandbox:/work/input.jsonmvmctl exec agent-sandbox -- python /work/task.pymvmctl cp --max-bytes 16777216 agent-sandbox:/work/output.json ./output.jsonCopy workflows reduce host exposure. Treat copied guest output as untrusted input when it returns to the host.
Snapshots versus volumes
Section titled “Snapshots versus volumes”Volumes preserve selected filesystem state. Snapshots preserve machine state.
| Capability | Volume | Snapshot or cold state |
|---|---|---|
| Files only | Yes | Yes |
| Process memory | No | Yes |
| Running process state | No | Backend-specific |
| Easier to inspect | Yes | No |
| Smaller retention surface | Usually | Usually not |
| Can contain secrets | Yes | Yes |
Use a volume when you need durable files. Use cold mode or snapshots when you need to resume a whole machine state.
Agent workspace pattern
Section titled “Agent workspace pattern”For a coding agent:
- Create a named sandbox with a short TTL.
- Copy the task input into
/work. - Mount a managed volume at
/workspaceonly if the agent needs durable state. - Keep network closed until the task has an approved egress need.
- Copy out bounded results.
- Stop, cold-pause, or destroy based on the retention decision.
- Lock volumes and record receipt/audit identifiers.
Example:
mvmctl volume create coding-agent-workmvmctl volume unlock coding-agent-workmvmctl up ./agent-image --name coding-agentmvmctl volume mount coding-agent --volume coding-agent-work --guest /workspace --rwmvmctl cp ./task.json coding-agent:/work/task.jsonmvmctl exec coding-agent --timeout 120 -- python /work/run_task.pymvmctl cp --max-bytes 16777216 coding-agent:/work/result.json ./result.jsonmvmctl volume unmount coding-agent /workspacemvmctl down coding-agentmvmctl volume lock coding-agent-workCleanup checklist
Section titled “Cleanup checklist”Before marking a stateful sandbox done:
- stop compute with
mvmctl downwhen it no longer needs to run; - lock every managed volume;
- remove mounts that are no longer needed;
- delete snapshots that no longer have a recovery purpose;
- rotate credentials if generated code had access to them;
- store receipt/audit identifiers with the job record;
- review logs before attaching them to tickets, traces, or model context.
Stopping compute is not the same as erasing state. Volumes, logs, receipts, snapshots, caches, copied files, and generated artifacts may remain.