On this page
← User GuidesDOCS · USER GUIDE
Lock down agent egress — the host-side firewall
A hands-on guide to the host-side egress firewall, which controls the traffic leaving a VM so an isolated agent cannot reach cloud metadata or your internal network at will. The default mode blocks credential theft through the cloud metadata service; a stricter mode blocks internal private networks as well. You can change the policy while the daemon is running, with no restart.
Last updated · 2026-07-28
1 · Overview
An agent decides on its own when to reach out over the network — and that autonomy is exactly where the risk starts. Under prompt injection, or with a tool that misbehaves, it can send requests to destinations you never intended. The most dangerous of those is the cloud metadata service. AWS, Google Cloud, Azure, and the other major clouds all serve it at the same link-local address, 169.254.169.254, commonly known as the IMDS (Instance Metadata Service). That address exposes the cloud credentials granted to the instance, so an agent that reaches it can leak keys that put your entire account at risk. Worse still, an attacker can follow that same path deeper into internal resources such as a corporate network or a database, which makes this a risk to guard especially closely.
A Vantisso agent already runs isolated inside a Firecracker MicroVM. But isolation alone cannot stop a threat like this, because the VM still has an open path out to the network. The egress firewall controls that path from the host side. Because it runs on the host rather than in the VM, an agent inside the VM can neither bypass nor disable it — and metadata blocking (imds) stays on by default, with nothing to configure.
The two paths out of a VM
Traffic leaving a VM takes one of two paths. One goes to the services on the host’s gateway IP (10.0.1.1) — the control-plane API and the MCP gateway; the other is routed out to the world beyond. The egress firewall sits in the kernel’s FORWARD chain, so it inspects and filters only the traffic headed outside. Traffic bound for host services traverses the INPUT chain instead, and the firewall configured here never touches it. That is why agent-team coordination and MCP tool calls behave the same under every policy.
Isolated guest — no host credentials
FORWARD chainforwarded packetsDROPACCEPTThe firewall policy comes in three modes: off turns the filter off completely, imds blocks only the cloud metadata range (the default), and strict blocks every private network and loopback address on top of metadata. You set the mode with the VANTISSO_NET_EGRESS environment variable, and you can change it through the API while the daemon runs, with no restart.
A guest cannot turn off its own firewall
PUT /net/egress, the endpoint that changes the policy, is operator-only. Group VMs are handed a control-plane callback token so that agent teams can work together, but the daemon uses the request’s source IP to work out whether the caller is a VM and refuses any call to an operator-only endpoint that comes from one. So even an agent that has been compromised or manipulated cannot switch off its own egress firewall, nor mint itself a new operator token. Control of the firewall stays with the host at all times.
2 · The default policy (imds)
Configuring and inspecting this firewall is a task only an operator with host access can perform. To keep the walkthrough simple, this guide assumes the plainest possible setup — working locally with API authentication disabled — which is why the curl commands that follow run as they are, with no credentials. Bear in mind that in a production deployment with API authentication enabled, these same calls have to be authenticated as an operator.
A fresh Vantisso install comes up with its egress policy set to the default mode, imds. This mode drops every routed packet a VM sends to the link-local range 169.254.0.0/16. That range contains the cloud metadata address 169.254.169.254, so the credential-theft path is closed from the very first boot. VMs on the 10.0.1.0/24 bridge have no use for link-local addresses when they talk to one another, so blocking the range in full leaves VM-to-VM traffic untouched.
| Destination range | Under imds |
|---|---|
169.254.0.0/16 (metadata, link-local) | blocked |
private networks 10/8 · 172.16/12 · 192.168/16 | allowed |
| public internet (model providers, external APIs, …) | allowed |
host services on 10.0.1.1 (CP API, MCP gateway) | allowed (INPUT chain) |
Confirm it’s applied
Check the line the daemon writes to its log automatically at startup.
# daemon startup log
msg="vm egress policy configured" mode=imds chain=VANTISSO_EGRESS allow=[] applied=trueYou can also query the policy currently in force through the control-plane API.
curl -s http://localhost:3000/net/egress
# → {"mode":"imds","allow":[],"available":true,"applied":true,"modes":["off","imds","strict"]}In the response, available tells you whether the host has the iptables needed to apply or change a policy, and applied tells you whether every rule for the reported mode was in fact installed. modes is the full list of policy modes you can choose from (off, imds, strict). Since the server is what decides which modes are valid, the Vantisso UI builds its mode selector from the list this call returns.
From now on, when an agent inside an isolated VM sends a request to 169.254.169.254, that request is dropped silently and times out with no response — in other words, the means of reading those credentials is gone entirely. Ordinary access to the public internet, a model-provider API for instance, remains allowed under the default policy.
3 · Harden with strict
In some environments, blocking IMDS is not enough on its own. The textbook case is one where the host running your agents is itself networked to systems inside your trust boundary — a corporate network, internal databases, other internal services. Outbound VM traffic is routed through that host, so a compromised agent can follow the very same path and work its way into those internal systems. The hardened strict mode therefore blocks every private range and loopback address as well, on top of the IMDS blocking of the default mode.
| Blocked range | What it covers |
|---|---|
169.254.0.0/16 | cloud metadata (IMDS), link-local |
10.0.0.0/8 | private network, class A |
172.16.0.0/12 | private network, class B |
192.168.0.0/16 | private network, class C |
127.0.0.0/8 | loopback |
Traffic to peer VMs on the same bridge is switched at L2 and never reaches this routing filter to begin with, so it keeps working under strict as well. Blocking private ranges will never disrupt the traffic an agent team relies on to collaborate.
You can set strict through the environment variable, as shown below, or through the runtime API call covered in the next section. Note that the environment variable is read just once, when the daemon starts, so any change to it takes effect only after a daemon restart.
# systemd: add a drop-in, then restart the daemon.
# under [Service]: Environment=VANTISSO_NET_EGRESS=strict
sudo systemctl edit vantisso
sudo systemctl restart vantisso4 · Allowlist exceptions
You also have to reckon with the flip side: strict mode blocks even the internal destinations you genuinely need. Say an agent absolutely must reach one particular internal API or artifact registry — you need a way to open just that range as an exception. For this, Vantisso supports allowlisted exceptions through VANTISSO_NET_EGRESS_ALLOW, which takes a comma-separated list of CIDRs.
# strict mode only. Add these to the daemon's systemd unit ([Service] section),
# then restart the daemon:
# Environment=VANTISSO_NET_EGRESS=strict
# Environment=VANTISSO_NET_EGRESS_ALLOW=10.5.0.0/16,192.168.9.0/24Every allowlisted range is placed ahead of the block rules as a pass (RETURN), and so takes precedence over them: an explicitly permitted destination is never caught by a drop rule further down. Note that this setting is meaningful only in strict mode. Under imds or off, an allowlist is ignored even if you supply one.
- Invalid CIDRs are left out — only the entries that fail to parse are ignored, with a warning; every remaining valid entry still applies.
- A request to allow the IMDS range is refused outright — a CIDR that would re-open
169.254.0.0/16(the catch-all0.0.0.0/0included) would defeat IMDS blocking, so it is rejected even when you explicitly ask for it.
5 · Change the policy live
When you are trying out a firewall policy, or responding to a security incident, you need a policy change to take effect immediately, without restarting the daemon. Vantisso’s operator-only GET/PUT /net/egress API lets you read and change the egress policy of a running daemon, no restart involved.
# Switch to strict, allowing one internal target, without a restart:
curl -s -X PUT http://localhost:3000/net/egress \
-H 'Content-Type: application/json' \
-d '{"mode":"strict","allow":["10.5.0.0/16"]}'
# → {"mode":"strict","allow":["10.5.0.0/16"],"available":true,"applied":true,"modes":["off","imds","strict"]}When you attempt a policy change and validation fails — the mode is not one of off, imds, or strict; a CIDR will not parse; a CIDR overlaps the cloud metadata range; iptables is missing for a mode other than off — the call returns 400 and leaves the existing policy exactly as it was. It is designed so that a malformed request can never leave the firewall hanging open.
When a runtime PUT re-applies a policy, there is a sub-millisecond window between flushing the chain and repopulating it in which the rules are briefly empty and traffic can slip through. This window exists only on a runtime re-apply, with VMs already up; the initial setup at boot finishes before any VM forwards traffic, so it does not arise there. Steady-state operation is unaffected.
Switching to off removes the jump that led from FORWARD into the firewall, leaving no overhead behind at all. That does, however, return you to the unrestricted behavior of releases before v0.8.8, so use it only when you have a clear reason to accept IMDS exposure.
6 · Prevent IP spoofing
Both the egress firewall and the MCP gateway identify the agent VM behind a request by its source IP. For that identity to hold up, one agent VM must not be able to impersonate another by using its IP address. VANTISSO_NET_ANTISPOOF, enabled by default, pins each VM’s bridge port to its assigned MAC and IP at L2, which shuts down IP impersonation at the source.
The mechanism is simple. On each TAP interface, ARP is allowed only when the source MAC matches (without this the guest cannot find the gateway and connectivity breaks altogether), IPv4 traffic is allowed only when both the source MAC and the source IP match, and anything else is treated as spoofed and dropped. These rules are held in a dedicated ebtables chain (VANTISSO_AS) and scoped to a single port each, so they never interfere with other VMs or with host traffic.
Anti-spoof is on by default, and it is built so that you can deliberately opt out by setting VANTISSO_NET_ANTISPOOF to 0/false/no/off. Note that if the host has no ebtables, it is implemented to log a warning and carry on with the protection disabled. To tell whether it is active, look for a per-TAP anti-spoof enabled line in the startup log.
7 · Operate and troubleshoot
What takes effect when
| What you changed | How it applies |
|---|---|
VANTISSO_NET_EGRESS · _ALLOW · _ANTISPOOF (environment variables) | restart the daemon |
PUT /net/egress (runtime policy change) | immediately (no restart) |
How to inspect it
- Check the current policy through the API: in
GET /net/egress, confirm thatmodeis the value you intended and thatappliedistrue. - Check the configuration printed in the startup log: confirm that the
vm egress policy configuredline carries the expectedmodeandapplied, and that aper-TAP anti-spoof enabledline is there. - Check the rules actually in place: on the host,
sudo iptables -t filter -nL VANTISSO_EGRESSshows the installed DROP/RETURN rules, andsudo ebtables -t filter -L VANTISSO_ASshows the anti-spoof pins.
If the host has no iptables or ebtables, the protection in question is quietly disabled with nothing but a warning. The daemon keeps running, but the firewall is not in force, so for a production deployment it is essential to check that both tools are properly installed on the host. If the response to GET /net/egress contains available: false, you know the host is missing iptables.
Next steps
For the exact shape of the API that reads and changes the egress policy, see the API Reference; for how to attach tools to isolated agents safely, see the MCP gateway guide. For a commercial license or an extended evaluation, contact sales@ax-onn.com.