Getting Started

Install Tubo on two machines, attach a local service, and share it with a one-time exact invite — the minimal Tubo flow, end to end.

The minimal flow: local service → tubo attach → exact invite → clean Tubo installation → short-lived Access Lease → authorized encrypted connectivity

1. Install

The easiest way to install Tubo is the one-line installer:

$ curl -fsSL https://www.tubo.click/install.sh | sh

By default this upgrades a writable existing tubo on PATH; otherwise it installs to ~/.local/bin. If you use the default location, make sure that directory is on your PATH.

Build from source:

$ git clone https://github.com/origama/tubo.git
$ cd tubo && go build -o tubo ./cmd/tubo

Verify the installation:

$ tubo version
tubo v0.13.0 (protocol 2.1, commit …, built …)

2. Attach your service (owner machine)

Run tubo attach next to any HTTP service, raw TCP/TLS service, or Unix socket. It defines the Service and its Pipe, then runs the Pipe. With -d the Pipe runs detached:

# Attach an HTTP service running on 127.0.0.1:8080
$ tubo attach http://127.0.0.1:8080 --name myapi -d

service/myapi created
pipe/myapi created
pipe/myapi ready (pid 12345)

The service stays local: it is never automatically public or discoverable. Reachability comes from an embedded, verified public bootstrap bundle — or from your own relay via tubo join overlay (see Private Swarms).

3. Share a one-time exact invite

tubo share provisions a dedicated Exact Pipe Authority key for the Pipe and mints a single-use, owner-signed invite bound to exactly that Pipe:

$ tubo share pipe/myapi

sharing pipe/myapi
one-time invite; expires in 10m0s
eyJ0eXAiOiJK...   # the invite (stdout carries exactly this)
recipient runs: tubo accept --token <invite>  (redeems once)
then, anytime:  tubo connect --remote pip_... --local 127.0.0.1:PORT
Exact invite: single-use, short-lived, bound to one Pipe ID and one owner. Redemption requires the recipient to prove possession of their identity key with a challenge-response. The invite is never an Access Lease — it only bootstraps one.

4. Connect from another machine (recipient)

On a clean Tubo installation, redeem the invite and get a local endpoint:

$ tubo connect --token <invite> --local 127.0.0.1:9000 -d

✓ Tunnel ready
  local       http://127.0.0.1:9000
  target     myapi  (pip_...)
  path        relayed via relay.tubo.click

$ curl http://127.0.0.1:9000/healthz
OK

The invite is redeemed exactly once and becomes a durable accepted binding. Later, tubo connect --remote pip_... --local 127.0.0.1:9000 reuses it — no new invite needed. Every remote open is authorized by a short-lived Access Lease that is renewed per open; leases expiring does not break connectivity.

5. Revoke and re-authorize

# Fence a not-yet-redeemed invite (JTI or full token)
$ tubo revoke invite <token-or-jti>

# Fence ALL access to the Pipe; a fresh share re-authorizes at the new epoch
$ tubo revoke pipe-access pipe/myapi

6. Manage runs

# List runs on this machine
$ tubo ps

# Follow logs
$ tubo logs pipe/myapi

# Stop and remove
$ tubo stop pipe/myapi
$ tubo rm pipe/myapi

Next steps