Statio

Documentation
API Reference
Changelog
concepts/Outbound control

Outbound control

Vaulting a credential stops an agent from reading it. It does not stop a compromised MCP server from taking the data it legitimately fetched and sending it somewhere else. Those are different problems, and the second one is not solved by encryption.

What it stops

An MCP server is code, usually someone else's, running with a real credential and receiving whatever your agents send it. Three ways that goes wrong, and all three end with the server opening a connection it has no business opening:

  • A compromised or malicious server. A package update, a typosquatted dependency, or a server that was never what it claimed. It can read every tool argument and every upstream response that passes through it.
  • Exfiltration. Customer records fetched from your CRM, a file read from a repository, the upstream response itself, posted to an address the attacker controls.
  • Prompt injection reaching out. An issue, email or document the agent reads tells it to call a tool with an attacker's URL in the arguments, and a server that fetches URLs will happily fetch it.

Outbound control does not decide which tools an agent may call; that is permissions. It decides where the server may connect once a call is running, whatever the call asked for.

The allowlist

Each managed server has a list of hosts it may reach. Anything else is refused.

An empty list is a real state, not a misconfiguration to warn about. A server that has not been told where it may go does not go anywhere.

api.stripe.com      exact host
*.example.com       one level of subdomain: api.example.com, NOT example.com
                    itself, and not a.b.example.com

A wildcard covers exactly one label. *.example.com does not match example.com, a.b.example.com or evil-example.com; list each of those the server needs.

Ports are part of the policy. Unless a server's policy says otherwise, only port 443 is allowed, because a list that names the right hosts but permits any port leaves alternate-port exfiltration open.

A refused connection carries one of these reasons:

ReasonMeaning
host is not in the server's allowlistThe destination is not on the list
port is not permittedThe host is listed, the port is not
no egress policy for this serverThe proxy could not find a policy for the caller, so it refused
destination could not be parsedThe proxy could not read where the server was trying to go

Why it is enforced outside the container

The obvious way to build this is a check inside the server: before making a request, consult the list. That works right up until the moment it matters. If an attacker controls the process, they control every check inside it. They open a socket and your allowlist is a comment.

So the list is enforced at a proxy the container does not control, and the container runs with no direct route to the internet. The proxy is the only way out. A raw socket to an IP address, an unusual port or a DNS tunnel all fail the same way: there is no route. A server that ignores its configuration does not get further than one that respects it.

The proxy identifies the server from its own proxy credential, not from anything in the request, so a compromised server cannot claim another server's list.

Refusals are visible

Blocked attempts are recorded with the host, port and reason. This is what teams read day to day: a destination appearing there that should be permitted is one you have not added yet, and the log says so instead of leaving you to guess from a timeout.

It also means an exfiltration attempt looks like something. A silent block and a working integration are indistinguishable from the outside. A block you can read is evidence.

Reading a server's list

Open the server under My MCPs and find the Outbound Access panel. What it shows depends on who runs the server:

ServerWhat the panel shows
One you deployed from an OpenAPI specThe allowlist, which you edit, and its status
A catalog server Statio runsManaged by Statio: the list comes with the catalog entry and is read-only
A vendor-hosted catalog server, or one you hostRead-only, with the reason: Statio does not run it, so its outbound traffic is controlled where it runs

The status reads Enforced, or Not yet enforced, redeploy to apply when the list has changed since the last deploy. Under it, Recent blocked connections lists each refused host:port with its reason and time.

Some catalog servers ask for a host when you install them, such as your own Jira site or a self-hosted product's URL. That host is allowed for your install on top of the entry's list.

Changing the list

Allowlists apply at deploy time. Add a host in Outbound Access, choose Save allowlist, redeploy the server, and the panel moves from "not yet enforced" to enforced. The delay is deliberate: outbound policy changing under a running server without a deploy would make the audit trail harder to reason about, not easier.

Allowlists are current state. Rolling a server back to an older version does not bring back the list it had then.

Note

Servers you host yourself are outside this boundary. Statio still governs who may call them and with which credential, but where your own infrastructure sends traffic is yours to control.

See also
Was this page helpful?
© Statio