Skip to main content
JavaScript examples use @beamcloud/beam-js 1.1.0 or later. Configure the SDK before running them.

Stable application URLs

Run a service on 0.0.0.0 and publish its port:
Each published port has a stable subdomain URL. Your application’s /, root-relative assets, redirects, and WebSockets use that origin without a VM path prefix. Always use the URL returned by Beam instead of constructing a hostname yourself.
get_url() only retrieves an already published URL; it does not expose a private port. Removing a published route does not stop the service:
URLs stay the same after stop/start or pause/resume. A fork or restored VM gets its own URLs. A URL cannot serve traffic while the VM is asleep unless automatic resume is enabled.

Persistent IPv6

When allocated, the VM’s public IPv6 address appears in beam vm new and beam vm get NAME. Print only the address with beam vm ip NAME. In Python, vm.public_ipv6 reads the resolved VM metadata without another request; it is None if no address has been allocated. The address survives stop/start and pause/resume. Published TCP ports use the same guest port number. From an IPv6-capable network, connect to a public application port or SSH directly:
SSH requires the private key matching the VM’s configured public key. beam vm ssh devbox uses the authenticated tunnel and also works from IPv4-only networks. The IPv6 address does not bypass port protection: protected HTTP ports still require the VM traffic token header. Use subdomain browser links below for terminal, desktop, and protected web apps; browser sessions cannot authenticate a raw IPv6 URL. This inbound address is not a fixed outbound source IP.

Protect a published port

New VMs protect the browser terminal (7681) and enabled desktop (8080) by default. Other published ports are public unless protected explicitly:
In Python, use ports and protected_ports to protect application ports at creation, or call expose(port, protected=True) later. Terminal and desktop protection needs no extra configuration:
Use beam vm new NAME --public-port 7681 or Python VM(public_ports=[7681]) to create a public terminal. Change protection on an existing terminal:
Python vm.expose(7681, protected=True) and JavaScript vm.exposePort(7681, { protected: true }) also toggle protection. Use 8080 for an enabled desktop. Existing VM specifications are not rewritten; protect older VMs with the commands above. System ports cannot be unexposed or bound, and SSH port 2222 cannot be published or toggled.

Browser access

beam vm desktop NAME, beam vm terminal NAME, and beam vm open NAME PORT generate an expiring entry URL automatically when their port is protected. Opening it exchanges the session credential for a Secure, HTTP-only cookie scoped to that port’s host, then redirects to the stable URL with the credential removed. Open any published HTTP application, or print its usable link:
Creation, get, expose, and ports also display usable links for protected ports; ports distinguishes public, protected, tunnel-only, and SSH access. beam vm expose devbox 8000 --protected --url prints only the usable link. JSON output keeps stable metadata URLs without embedding temporary credentials; mint a link separately with beam vm access-url devbox 8000 --ttl 600. Generate an entry URL from an SDK:
Session TTLs are 1–3600 seconds; the default is 600 (10 minutes), including CLI-generated links. Anyone holding a link can access that port until expiry, so treat it as a credential. If a stable URL reports VM traffic token required, use beam vm open NAME PORT for a fresh link. Rotating the traffic token revokes browser sessions. Through MCP, use vm_access_url, which requires the beam:credentials scope.

Programmatic access

For HTTP clients, use the VM traffic token in X-Beam-VM-Token. This token is distinct from your workspace API token:
Rotate it to revoke the old token and browser sessions:
In Python, use vm.traffic_access_token and vm.rotate_access_token(). The gateway removes the traffic token header and its browser session cookie before proxying to the application. To avoid handling traffic tokens in a local client, use port forwarding.

JavaScript HTTP clients

Private TCP forwarding

Keep a database or other TCP service private and connect through localhost:
The service must already be running in the VM. Configure its application credentials separately. The forwarding listener binds to 127.0.0.1; the command keeps running until you stop it. Equivalent syntax is beam vm port-forward devbox 5432 --local-port 15432. Port forwarding binds an unpublished port for authenticated tunnels without creating a public HTTP URL. SSH uses the same private transport. In Python, vm.bind(5432) makes a port available to authenticated tunnels without publishing it. The low-level beam vm tunnel NAME PORT command bridges a tunnel through stdin/stdout, for tooling integrations; use ssh or port-forward for normal interactive use.

JavaScript TCP streams

Port forwarding and raw streams reconnect using the same resumable private transport. Closing their handles, or vm.close(), releases local listeners and connections.

Outbound network controls

Block outbound traffic or allow only specific hostnames, wildcard domains, IPs, or CIDRs:
Allowlists accept up to 64 entries, including bare IPv4/IPv6 addresses and CIDRs. A bare address means one host (/32 for IPv4, /128 for IPv6). *.example.com matches subdomains, excluding example.com itself. Hostname rules contain no scheme, path, or port. Hostname rules match TLS SNI on port 443 or the HTTP Host header on port 80. Other TCP ports and protocols need an IP or CIDR rule. The proxy rejects private, loopback, and link-local destinations, including explicit IP/CIDR targets; an allowlist does not create private-network access. Under an allowlist, UDP and ICMP are blocked except DNS to the configured resolver. Rules persist across restarts. Updates close existing connections and take effect without restarting the VM. Do not combine block_network=True with an explicit allowlist.
Use --block-network or repeat --allow-network HOST_OR_CIDR at creation. With brokered secrets, blocking allows only their approved credential hosts; an explicit allowlist must cover those hosts with hostname rules and is never widened by a secret. IP/CIDR entries alone do not cover credential hosts. With the default open policy, host rules restrict credential substitution without closing other outbound access. Proxied TCP connections originate from the worker, including connections to CIDR targets. Use the worker’s source IP in downstream access rules. Guest egress rules apply to downloads and API calls, but not to image builds. Egress restrictions do not protect inbound URLs. Configure published-port protection independently.