Docs

Tunnels

A tunnel lets your backend call an HTTP service running inside a deployment, without the customer opening anything inbound. The Operator in the deployment keeps an outbound WebSocket connection to your manager, and requests you send to the manager travel over it to the container.

your backend ──HTTPS──▶ manager ══ Operator's outbound connection ══ Operator ──HTTP──▶ container

Tunnels work with pull deployments, where the Operator runs in the customer's environment, including Kubernetes.

Declare a tunnel

Name the container port your backend may reach:

alien.ts
const api = new alien.Container("api")
  .code({ type: "image", image: "ghcr.io/acme/api:latest" })
  .port(8080)
  .tunnel(8080)
  .build()

Only declared ports are reachable, and nothing is exposed on the customer's network. Operators older than tunnels receive the release without the declaration and keep deploying it; the tunnel starts working once they update.

Call it

/v1/deployments/{deployment}/tunnels/{container}/{path}

{deployment} is the deployment's ID, or its name when that is unique. Everything after the container name, including the query string, is the path the container receives.

curl https://manager.example.com/v1/deployments/acme/tunnels/api/objects?prefix=reports/ \
  -H "Proxy-Authorization: Bearer ax_tunnel_..." \
  -H "Authorization: Bearer <the application's own token>"
  • Proxy-Authorization authenticates you to the manager. The manager removes it before forwarding.
  • Authorization and every other end-to-end header reach the container unchanged, so the application keeps its own authentication.
  • The container sees X-Forwarded-Proto and X-Forwarded-Host for the manager's public URL.

Request and response bodies stream in both directions with flow control, so large uploads and downloads don't buffer in the manager or the Operator. Many requests share one connection concurrently. Tunnels carry HTTP requests; WebSocket upgrades and raw TCP are not forwarded.

Tokens

Give your backend a token that can only call tunnels, instead of an admin key:

alien tokens create --tunnel                    # every deployment
alien tokens create --tunnel --customer acme    # one customer's deployments

A tunnel token can't read releases, deployments, or logs. Revoke it with alien tokens revoke <id>; requests using it fail immediately. See Tokens.

Turn tunnels off

In a customer's install, --set tunnel.enabled=false stops the Operator from connecting, and requests for that deployment fail with 503 TUNNEL_NOT_CONNECTED.

Errors

Errors produced by the tunnel, rather than by your container, carry an alien-tunnel-error header with the code:

StatusCodeMeaning
401Missing or invalid Proxy-Authorization
403The token can't call this deployment's tunnels
404TUNNEL_TARGET_NOT_FOUNDThe container declares no tunnel
502TUNNEL_UPSTREAM_UNAVAILABLEThe container didn't answer
502TUNNEL_REQUEST_FAILEDThe connection to the Operator broke mid-request
503TUNNEL_NOT_CONNECTEDThe deployment's Operator isn't connected

The Operator reconnects on its own after network interruptions and manager restarts.

Proxies and load balancers

Operators hold their connection open. If a proxy or load balancer sits in front of the manager, allow WebSocket upgrades on /v1/tunnel/connect and set idle timeouts well above 20 seconds, the interval of the tunnel's keepalive pings.

On this page