Guides
Network egress policy
Apply deny-first outbound network rules for agents, services, package installs, and browser automation.
Network access is a sandbox capability. Treat it like filesystem writes or secret grants: start closed, add the smallest destination set that makes the workload useful, and record why the grant exists.
This page focuses on outbound egress. For backend network layout and port forwarding mechanics, see Networking.
Policy levels
Section titled “Policy levels”| Level | Use when | Example |
|---|---|---|
| No egress | Generated code, code interpreters, offline analysis. | (default — deny-all) |
| Package registries | Build or install steps need language registries. | --net |
| Local development | A developer needs common dev services. | --net |
| Explicit allowlist | Production-like agent or service path. | --allow-host api.example.com:443 |
| Unrestricted | Local debugging only. | Avoid for untrusted workloads. |
For security-sensitive examples, use no egress or explicit allowlists. Broad presets are convenience tools, not production policy.
CLI patterns
Section titled “CLI patterns”Start closed:
mvmctl machine run --flake . --name agent-sandboxAllow only package registries for install-heavy workflows:
mvmctl machine run --flake . --name build-sandbox --netAllow named destinations:
mvmctl machine run --flake . --name agent-sandbox \ \ --allow-host api.openai.com:443 \ --allow-host github.com:443Keep inbound ports separate from outbound egress:
mvmctl machine run --flake . --name api-dev --port 8080:8080Opening a host port does not mean the guest should have outbound internet access.
SDK declaration pattern
Section titled “SDK declaration pattern”Static declarations should make network posture reviewable:
network=mvm.network(mode="none")For a reviewed outbound grant:
network=mvm.network( mode="bridge", egress=mvm.egress([ mvm.host_port("api.openai.com", 443), ]), dns=mvm.dns_system(),)network: mvm.network({ mode: "none" })For a reviewed outbound grant:
network: mvm.network({ mode: "bridge", egress: mvm.egress([ mvm.hostPort("api.openai.com", 443), ]), dns: mvm.dnsSystem(),})Use Declaration cookbook for the full decorator shape.
Agent tool policy
Section titled “Agent tool policy”Do not let a model choose arbitrary network destinations. The application should map a capability to a fixed grant:
{ "tool": "web_fetch", "network": { "mode": "bridge", "allow": [ { "host": "api.openai.com", "port": 443 } ] }}Validation rules:
- reject wildcard hosts, CIDRs, and user-provided raw proxy URLs unless the policy explicitly supports them;
- allow only expected ports for each tool capability;
- keep DNS policy explicit when the workload depends on names;
- treat outbound detect/replace and inbound plaintext reinjection as separate policy decisions;
- store the grant decision with the audit/run identifier;
- return policy denial distinctly from transport or guest command failure.
If a tool path is allowed to send secrets or user data to a remote service, prefer runtime-owned mediation over raw pass-through. On owned cleartext paths, the runtime can detect secrets and structured PII, replace them with opaque flow-scoped tokens, and restore the original bytes only when the exact token returns on the owned response path. Do not claim this as general content reconstruction: paraphrased or transformed remote output should stay redacted or tokenized.
Browser and desktop automation
Section titled “Browser and desktop automation”Browser and desktop automation should be treated as high-risk network users. They may carry cookies, sessions, downloads, and rendered user data.
Use a dedicated profile:
- no broad host mounts;
- short TTL;
- explicit egress allowlist;
- isolated persistent workspace if state must survive;
- no credential-bearing browser profile unless the task requires it;
- cold state or snapshots retained only with a clear retention rule.
AI egress metering and budgets
Section titled “AI egress metering and budgets”When a workload is allowed to call AI APIs, you can meter token usage and
cap it with a budget. Enable metering in the [network.ai] section of
mvm.toml:
[network]allow_hosts = ["api.openai.com:443"]
[network.ai]metering = true
[network.ai.budget]max_total_tokens = 1_000_000max_input_tokens = 500_000max_output_tokens = 500_000Equivalent SDK declarations:
network=mvm.network( mode="bridge", egress=mvm.egress([ mvm.host_port("api.openai.com", 443), ]), ai=mvm.ai_policy( metering=True, budget=mvm.ai_budget( max_total_tokens=1_000_000, max_input_tokens=500_000, max_output_tokens=500_000, ), ),)network: mvm.network({ mode: "bridge", egress: mvm.egress([ mvm.hostPort("api.openai.com", 443), ]), ai: mvm.aiPolicy({ metering: true, budget: mvm.aiBudget({ maxTotalTokens: 1_000_000, maxInputTokens: 500_000, maxOutputTokens: 500_000, }), }),})Behavior:
- Metering only inspects traffic to known AI providers (
api.openai.com,*.openai.azure.com,api.anthropic.com). Arbitrary destinations are not parsed. - Only provider-reported usage is counted. For OpenAI, set
stream_options.include_usage=trueso streamed responses include a trailing usage block; Anthropic includes usage automatically. - Budget enforcement is best-effort at response time: the request that crosses the budget is allowed and recorded; the next AI request is refused.
- Metrics are published as
mvm_instance_ai_requests_total,mvm_instance_ai_tokens_input_total,mvm_instance_ai_tokens_output_total, andmvm_instance_ai_tokens_total_total. Audit records contain counts and provider/model metadata only — never request or response bodies, headers, or credentials.
Backend enforcement notes
Section titled “Backend enforcement notes”The enforcement mechanism is backend-specific:
- Linux Firecracker paths can enforce bridge traffic with host firewall rules.
- macOS backends enforce through their host-side network layer.
- Some local debugging backends may have weaker isolation tiers.
Docs and examples should describe the product policy first, then name backend limits where the mechanism matters. Do not turn a backend convenience path into a product security claim without tests and claim-ledger evidence.
Review checklist
Section titled “Review checklist”Before allowing egress:
- name the exact host and port;
- confirm why the workload needs it;
- confirm whether DNS is needed;
- confirm whether the destination can receive secrets or user data;
- confirm logs and receipts will not expose payload data;
- confirm cleanup or retention behavior for any downloaded files.