Guides
Secrets and credentials
Use secret references, grants, redaction, and narrow delivery paths for sandboxed workloads.
Secrets are not ordinary configuration. A sandbox can print them, copy them, persist them in snapshots, or expose them through files and logs if the workflow is careless. Treat credential delivery as a policy decision with a reviewable grant.
Preferred model
Section titled “Preferred model”| Step | Rule |
|---|---|
| Store | Store a named secret reference with the local secret store. |
| Declare | Reference the secret by name in a manifest, declaration, or SDK request. |
| Grant | Bind the reference to a workload, command, or tool operation. |
| Deliver | Prefer host-mediated release paths over raw guest-visible values. |
| Redact | Scrub stdout, stderr, logs, errors, receipts, and model-facing results. |
| Retain | Treat snapshots, cold state, volumes, and copied files as secret-bearing until proven otherwise. |
The secure default is reference-first. Raw values should not appear in source files, examples, command history, model prompts, or long-lived logs.
Detect, replace, and reinject
Section titled “Detect, replace, and reinject”For owned cleartext request paths, mvm can mediate caller-visible content in addition to managed secret refs:
| Step | Behavior |
|---|---|
| Detect | Match declared secrets plus structured PII such as email, us_ssn, credit_card, e164_phone, and iban. |
| Replace | Rewrite matched bytes to request-scoped opaque tokens before they leave the runtime-owned path. |
| Reinject | Restore the original bytes only when the exact token returns on an owned cleartext response path and policy allows plaintext reinjection. |
| Fallback | If the path is unowned, transformed, expired, unauthorized, or uncorrelatable, do not restore; fall back to redaction, denial, or pass-through per policy. |
This is an exact-token contract, not semantic recovery. If a model paraphrases, splits, reformats, or partially copies the sensitive value, the runtime should not guess. Reinjection is for exact opaque-token round trips only.
Cloud deployments should keep reinjection policy load-bearing at the control plane: which classes are handled, which sinks may receive replacements, which callers may receive plaintext restoration, and how long correlation state is retained.
CLI flow
Section titled “CLI flow”Store a named reference:
mvmctl secret put openai-api-keyDeclare the reference in a workload manifest or SDK declaration, then run under
the policy that grants that reference to the workload. Avoid passing secrets
through argv or --env; those paths are easy to leak through process listings,
shell history, debug output, and crash reports.
SDK declarations
Section titled “SDK declarations”env={ "OPENAI_API_KEY": mvm.secret("openai-api-key", type="bearer", hosts=["api.openai.com"], var="OPENAI_API_KEY"),}const env = { OPENAI_API_KEY: mvm.secret("openai-api-key", { type: "bearer", hosts: ["api.openai.com"], var: "OPENAI_API_KEY" }),};The declaration records the reference. It should not contain the credential value.
Runtime SDK target
Section titled “Runtime SDK target”The runtime SDK target should preserve the same shape:
import mvmfrom mvm import Sandbox
with Sandbox.create( image="nix:./flake#agent-runtime", env={ "OPENAI_API_KEY": mvm.secret( "openai-api-key", type="bearer", hosts=["api.openai.com"] ) },) as sandbox: sandbox.commands.run(["python", "/work/tool.py"], timeout_seconds=30)import { Sandbox, SecretRef } from "@mvm/sdk";
using sandbox = await Sandbox.create({ image: "nix:./flake#agent-runtime", secrets: { OPENAI_API_KEY: SecretRef.from("openai-api-key") },});
await sandbox.commands.run(["node", "/work/tool.js"], { timeoutSeconds: 30,});Check Operations cookbook and Lifecycle matrix before treating a helper as shipped in a language SDK.
File-mounted secrets
Section titled “File-mounted secrets”Some workloads still need file-shaped secrets, certificates, or config bundles. When using a secrets drive:
- mount the narrowest directory possible;
- keep files read-only inside the guest;
- use non-secret test data in docs and fixtures;
- do not share the same mounted directory across unrelated workloads;
- treat snapshots and cold state as secret-bearing after the mount has been visible to a guest;
- remove or rotate credentials after a workflow that allowed generated code to read them.
Prefer managed secret references for credentials. Use file mounts for formats that cannot reasonably be expressed as references.
Agent and model workflows
Section titled “Agent and model workflows”Models should never invent secret names or values. The application should map a tool capability to an allowed reference:
{ "tool": "web_fetch", "secrets": { "OPENAI_API_KEY": { "ref": "openai-api-key" } }}Rules for model-facing tools:
- grant secrets per operation;
- keep PII handling explicit alongside secret grants;
- never echo resolved values to the model;
- treat restored plaintext as a separate permission from outbound replacement;
- redact command output before it becomes model context;
- reject requests that ask to print, exfiltrate, or persist credentials;
- record the grant decision with the audit/run identifier.
Redaction and failure handling
Section titled “Redaction and failure handling”Every secret-bearing path should have a failure behavior:
| Path | Failure behavior |
|---|---|
| Missing reference | Fail closed before VM launch or command execution. |
| Unauthorized reference | Return policy denial, not a generic runtime failure. |
| Structured PII detected on an owned outbound path | Replace with an opaque token when policy enables it; otherwise redact or deny per policy. |
| Guest prints a secret | Redact before logs or model-facing responses leave the app. |
| Exact opaque token returns on an owned response path | Reinject only when correlation and permissions are still valid. |
| Token returns from an unowned or transformed path | Do not reinject; keep the replacement or redact the value. |
| Cleanup fails | Report cleanup failure separately and mark retained state as sensitive. |
| Snapshot retained | Attach retention metadata and delete or rotate when no longer needed. |
Do not collapse secret failures into generic command errors. Operators need to know whether a workload failed because of policy, missing credentials, guest behavior, PII mediation, reinjection authorization, or cleanup.