Expose local services through self-hosted or public relays.
No port forwarding. No inbound firewall rules. No manual DNS setup. No accounts.
Portal is a local tunnel runtime and relay network for publishing services to the agentic web. It publishes local apps, APIs, tools, and agents through self-hosted or public relays, keeps routing and x402 payment policy in the tunnel process, and avoids requiring a hosted vendor account.
-
Self-Hostable, Fully Open Source - Run your own relay with a single command. The relay is MIT-licensed with no enterprise tier, no feature gating, and no call-home. Your relay, your rules.
-
Anonymous Relay Network - Connect to public relays without a hosted account or central operator. Combine self-hosted relays with public relays in a pool to split trust across independent operators you choose.
-
End-to-End Tenant TLS And ECH - Because relays are trustless, Portal terminates tenant TLS at the user's endpoint instead of the relay. Portal also provides ECH to avoid exposing the real hostname in plaintext SNI.
-
Built-in MITM Detection - Portal actively self-probes its own connection after real traffic begins. It compares TLS keying material exported on both sides and treats a mismatch as suspected relay-side TLS termination.
-
Multi-Hop Relay Routing - Chain multiple relays together so no single relay knows both the origin and the destination. Use
--multi-hop-depth 3to select a three-hop route automatically. -
No Accounts, No API Keys - Authentication uses SIWE-compatible signing with a locally generated secp256k1 key pair. No email, no registration, no vendor lock-in.
-
Built-in x402 Payments - Routed HTTP paths can require Sui gasless USDC x402 payment before proxying. Browser apps can import
/x402/client.js, and native clients can call/x402/preparedirectly and sendX-PAYMENT.
| Portal | ngrok | Cloudflare Tunnel | frp | |
|---|---|---|---|---|
| Public localhost URL | Yes | Yes | Yes | Yes |
| Self-hostable | Yes | Enterprise only | No | Yes |
| Open source | MIT | No | Client only | Apache 2.0 |
| Custom domain | Yes | Paid plans | Yes | Yes |
| End-to-end tenant TLS | Yes | No | No | No |
| SNI hiding (ECH) | Yes | No | No | No |
| MITM self-probe | Built-in | No | No | No |
| Multi-relay failover | Yes | Managed | Built-in | No |
| Multi-hop routing | Yes | No | No | No |
| Account required | No | Yes | Yes | No |
| Native x402 payments | Yes | No | No | No |
macOS / Linux:
curl -fsSL https://github.com/gosuda/portal-tunnel/releases/latest/download/install.sh | bash
portal expose 3000Windows (PowerShell):
$ProgressPreference = 'SilentlyContinue'
irm https://github.com/gosuda/portal-tunnel/releases/latest/download/install.ps1 | iex
portal expose 3000Portal prints a public HTTPS URL for your local app instantly. More examples:
# Custom name and relay
portal expose 3000 --name myapp --relays https://portal.example.com --discovery=false
# Mount frontend and API behind one URL
portal expose --name myapp \
--http-route /api=http://127.0.0.1:3001 \
--http-route /=http://127.0.0.1:5173
# Require Sui USDC x402 payment before proxying a route
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...
# Raw TCP port (Minecraft, databases, SSH)
portal expose localhost:25565 --name minecraft --tcp
# Three-hop route for maximum anonymity
portal expose 3000 --multi-hop-depth 3See CLI Reference for the full route syntax and API Reference for the x402 helper endpoints.
Use portal agent run when tunnels should keep running outside your terminal.
It runs as a local OS service, keeps every tunnel in one TOML config alive, and
provides a dashboard for relay and multi-hop management.
portal agent run --config config.toml
portal agent dashboard --config config.toml
portal agent restart
portal agent stop
# Foreground mode skips OS service installation.
portal agent run --config config.toml --foregroundSee Portal Agent for the config format.
git clone https://github.com/gosuda/portal-tunnel
cd portal-tunnel && cp .env.example .env
docker compose upFor public deployment with DNS automation (ACME), TCP/UDP port ranges, and relay policy, see Deployment.
Browser
-> Relay SNI router (reads only routing token, forwards raw bytes)
-> Reverse session
-> Portal tunnel (performs TLS handshake locally, derives session keys)
-> Local service
- The relay accepts the incoming connection and reads only the TLS ClientHello for SNI-based routing.
- It forwards the raw encrypted stream over the reverse session without terminating TLS.
- The Portal tunnel on your side completes the TLS handshake locally. Session keys are derived on your machine.
- For relay-hosted domains, the tunnel obtains certificate signatures via
/v1/sign, using the relay only as a keyless signing oracle. The relay signs handshake digests but never receives session keys. - After the handshake, the relay continues forwarding ciphertext without access to plaintext.
When ECH is enabled, the relay also cannot see the actual tenant hostname. It routes by an opaque token derived from the tunnel identity, while the real SNI stays inside the ECH-protected ClientHello.
Browser
-> Entry relay (sees only the opaque route hostname)
-> Middle relay (sees only the next-hop token)
-> Exit relay (sees only the reverse session token)
-> Portal tunnel
-> Local service
Each relay in the chain knows only its immediate neighbors. No single relay holds the full path. Tenant TLS still terminates only on your side, so no relay in the chain receives tenant TLS plaintext.
Portal's official public relay registry is:
https://raw.githubusercontent.com/gosuda/portal-tunnel/main/registry.json
Tunnel clients include this registry by default. If you operate a public Portal
relay, open a pull request to add your relay URL to registry.json.
- CLI Reference
- Concepts
- Portal Agent
- Wallet and ENS
- Security Model
- Architecture
- Deployment
- Configuration Reference
- Fork the repository.
- Create a feature branch (
git checkout -b feature/amazing-feature). - Make the change with focused tests or docs.
- Open a pull request.
MIT License - see LICENSE.
