Skip to main content

What are Private Networks?

A private network lets your sandboxes talk to each other directly. Each member is reachable from the others at <sandbox-id>.sandbox.internal, and the network’s rules decide who may connect to whom, and on which ports. Nothing outside the network can reach its members this way, unless a rule exposes a port to the internet. Common use cases:
  • Run a client and a server in separate sandboxes, such as an agent and the service it is being evaluated against
  • Split a workload into tiers, for example web sandboxes that may reach a db sandbox on port 5432 and nothing else
  • Spin up a small cluster for distributed tests without exposing anything to the internet
  • Publish a web app, API or dashboard running in a sandbox at a public HTTPS URL
Private networks connect running VM sandboxes that belong to the same team, or to you personally if you are not using a team. A network and all of its members must belong to the same owner.

Complete Example

Here’s a full working example: one sandbox serves HTTP on port 8000, and a second sandbox reaches it by name. 1. Create two sandboxes
2. Create a network and add both sandboxes
3. Start a server in one sandbox and call it from the other
A new network allows every member to reach every other member on every port, so the request returns 200.

Rules

Rules narrow who may connect to whom. Each rule is directed and allow-only: it lets members matching from open TCP connections to members matching to, on the listed ports. A connection that no rule allows is refused. A selector is either * (every member) or tag:<name> (members carrying that tag). Leave out the ports to allow every port.
Each call replaces the whole rule list. Pass several rules to allow several paths:
A few things to keep in mind:
  • Rules are directed. tag:web->tag:db lets web connect to db, not the other way around. Replies on an allowed connection flow normally.
  • The default is open. A new network starts with the single rule *->*. Replace it to restrict traffic.
  • An empty rule list blocks everything. Members stay in the network but cannot connect to each other.

Tags

Tags are labels on a member that rules select with tag:<name>. Set them when you add a sandbox. Adding a sandbox that is already a member replaces its tags.
Tags use lowercase letters, digits, ., _ and -, start with a letter or digit, and are at most 63 characters long.

Reaching Other Members

Inside a member sandbox, every other member resolves at <sandbox-id>.sandbox.internal. Use that name as the host for any TCP client:
  • Names resolve to private addresses in 198.18.0.0/15. These addresses are per sandbox and may change, so always connect by name.
  • Only TCP is supported between members.
  • A sandbox can belong to several networks at once. It can connect to a member of any of them, as each network’s rules allow.

Reaching Members at localhost

Some workloads expect their dependencies on localhost, for example an app hard-coded to localhost:5432 that normally runs next to its database in one container or pod. A localhost forward makes a port on the sandbox’s own loopback reach the same port on another member, so that code runs unchanged.
Inside the web sandbox, localhost:5432, 127.0.0.1:5432 and [::1]:5432 now connect to <db-sandbox-id>.sandbox.internal:5432:
Forward several ports, to the same peer or to different ones, in one call:
A few things to keep in mind:
  • Rules still apply. A forward is a shortcut to <peer>.sandbox.internal, not a way around the network. Both sandboxes must share a network whose rules let this sandbox reach the peer on that port, or connections are reset.
  • Same port on both ends. localhost:5432 always reaches port 5432 on the peer. Ports cannot be remapped.
  • The port must be free. The forward listens on the sandbox’s loopback, so it fails if something in the sandbox already uses that port. Likewise, a server started later on that port cannot bind it while the forward exists.
  • Each call replaces the whole set. Include every forward you want to keep. Changing a port’s peer applies to new connections; existing ones finish on the old peer.
  • TCP only, and at most 64 forwards per sandbox.
  • Recreate older sandboxes. A sandbox created before this feature was available returns an error saying it does not support localhost forwards.

Exposing Ports to the Internet

A rule with from set to internet publishes ports of the members matching to at a public HTTPS URL:
Requests reach your server with their path, query and headers unchanged, so any HTTP server works, such as a web app, an API or a dashboard.
Then start a server on that port and open its URL:
A few things to keep in mind:
  • Anyone with the URL can connect. Prime does not authenticate these requests. Add your own authentication if the service should not be public.
  • List the ports. An internet rule must name its ports, and it exposes only those. Ports 49983 and 2222 are reserved for the sandbox API and SSH, and cannot be exposed.
  • Listen on 0.0.0.0. A server bound only to 127.0.0.1 inside the sandbox cannot be reached from its public URL.
  • HTTP only. The URL serves HTTP requests. Other TCP services, such as databases, are reachable only from other members of the network.
  • The sandbox must be a member. Only members matching to are exposed. Removing the sandbox from the network, changing its tags, or deleting the network stops the exposure within seconds.
  • Public and private access are separate. An internet rule gives members no access to each other, and a rule like *->* exposes nothing publicly. Each call replaces the whole rule list, so include your private rules too:
A port that no rule exposes returns 404 Port not exposed. A sandbox that does not exist returns the same response, so the URL reveals nothing about which sandboxes exist.

Managing Networks

Changes apply within a few seconds. Until they do, the network or member shows as not yet synced, and Prime keeps retrying in the background. Removing a sandbox from a network cuts it off right away. Its connections to the other members are refused, including connections to addresses it looked up earlier. A sandbox that stops running leaves its networks automatically. AsyncSandboxClient has the same methods for async code. Pass team_id to create_lan_network and list_lan_networks (or --team-id on the CLI) to work with a specific team. Otherwise your configured team is used.

Limits

Quick Troubleshooting

  • “Only running sandboxes can join a network”: wait until the sandbox is RUNNING, then add it.
  • “Only VM sandboxes can join a network”: private networks are available for VM sandboxes only.
  • “The sandbox and the network must belong to the same team or user”: create the network under the same team as the sandbox, or switch your configured team.
  • Name does not resolve: names resolve only inside a sandbox that belongs to a network. Check that prime sandbox network get <network-id> lists the sandbox as a synced member.
  • Connection refused or reset: no rule allows that path. Check the direction and ports with prime sandbox network get <network-id>.
  • Localhost forward fails because the port is already bound: something in the sandbox already listens on that port. Stop it or forward a different port.
  • Connecting to a forwarded localhost port is reset: no rule lets this sandbox reach the peer on that port, or the peer has nothing listening on it.
  • Public URL returns 404 Port not exposed: no internet rule exposes that port on the sandbox. Check that the sandbox is a synced member whose tags match the rule’s to, and that the port is listed.
  • Public URL returns 502: the port is exposed, but nothing inside the sandbox accepts connections on it. Check that your server is running and listens on 0.0.0.0.