Portal CLI
cmd/portal-tunnel builds the portal CLI. It exposes local services through
Portal relays without inbound firewall rules, port forwarding, or manual DNS
setup.
The relay owns transport, lease registration, routing, and relay policy. The tunnel process owns local proxy behavior, routed HTTP policy, x402 route payments, and tenant TLS termination for the default HTTPS stream path.
Quick Start
Install from GitHub release assets:
curl -fsSL https://github.com/gosuda/portal-tunnel/releases/latest/download/install.sh | bash
portal expose 3000
$ProgressPreference = 'SilentlyContinue'
irm https://github.com/gosuda/portal-tunnel/releases/latest/download/install.ps1 | iex
portal expose 3000
If a relay publishes its own installer:
curl -sSL https://portal.example.com/api/install.sh | bash
portal expose 3000 --relays https://portal.example.com --discovery=false
Modes
Default HTTPS stream for most local web apps:
portal expose 3000 --name myapp
Routed HTTP when one public URL should mount multiple local HTTP upstreams:
portal expose --name myapp \
--http-route /api=http://127.0.0.1:3001 \
--http-route /=http://127.0.0.1:5173
Paid routed HTTP with Sui USDC x402:
portal expose --name paid-app \
--http-route "/paid=http://127.0.0.1:3001 GET:0.01" \
--http-route /=http://127.0.0.1:5173 \
--x402-pay-to 0x...
Routed HTTP serves /x402/client.js and /x402/prepare on the tunnel origin so
an upstream browser frontend can run the same in-page Sui wallet payment flow as
the standalone payment app. Native clients should use /x402/prepare directly
and send the signed payload as X-PAYMENT. The tunnel still verifies and
settles payment before proxying the paid route. Paid routes use Sui mainnet by
default; add --x402-testnet to use Sui testnet.
Raw TCP and UDP:
portal expose localhost:25565 --name minecraft --tcp
portal expose localhost:8080 --udp --udp-addr localhost:19132 --name game
Commands
portal expose [flags] <target>
portal expose [flags] --http-route "PATH=UPSTREAM [METHOD[,METHOD...]:USDC_AMOUNT]" [...]
portal list [flags]
portal agent run [flags]
portal agent dashboard [flags]
portal agent stop [flags]
portal agent restart [flags]
portal update
portal version
Common portal expose flags:
--name Public hostname prefix; auto-generated when omitted
--relays Additional relay API URLs, comma-separated
--discovery Include registry relays and relay discovery expansion
--max-active-relays Maximum auto-selected relays
--multi-hop Ordered multi-hop relay API URLs, comma-separated
--multi-hop-depth Automatically select one multi-hop route with this hop count
--ban-mitm Ban relay when the MITM self-probe detects termination
--identity-path Identity JSON file path; created automatically when missing
--identity-json Identity JSON payload; overrides --identity-path when set
--description Service description metadata
--tags Service tags metadata, comma-separated
--thumbnail Service thumbnail URL metadata
--owner Service owner metadata
--hide Hide service from relay listing screens
--http-route HTTP route mapping in PATH=UPSTREAM [METHOD[,METHOD...]:USDC_AMOUNT] form
--x402-pay-to Sui USDC payment recipient address for this tunnel
--x402-testnet Use Sui testnet for tunnel x402 payments
--tcp Request a dedicated raw TCP port on the relay
--udp Enable public UDP relay
--udp-addr Local UDP target
--metrics-addr Optional host:port for Prometheus /metrics
Agent
Use the agent for durable multi-tunnel operation from one config file:
portal agent run
portal agent dashboard
portal agent stop
portal agent restart
The dashboard can edit basic tunnel settings, relays, and multi-hop routes. Add
Tunnel opens a small form for name, target or HTTP routes, x402 pay-to/testnet,
relays, discovery, and max active relays. After creation, routed HTTP paths,
route-level x402 amounts, payment network, and discovery mode are read-only in
the Settings pane. Edit http_routes, x402_pay_to, x402_testnet, or
discovery in TOML, then restart the agent or tunnel to change them.
Constraints
- A positional
<target>cannot be combined with--http-route. --http-routecannot be combined with--udp.- Route payment amounts are USDC values such as
0.01, are part of--http-route, and require--x402-pay-to; add--x402-testnetfor Sui testnet, otherwise payments use Sui mainnet. --multi-hopcannot be combined with--multi-hop-depth.- Multi-hop currently supports only the default SNI TLS stream transport.
--tcpand--udprequire matching relay transport support.