Back to Linux guides

zrok: Zero-Trust localhost Tunneling for Public and Private Sharing

Stanley Ulili
Updated on April 15, 2026

zrok is an open-source sharing tool by NetFoundry that exposes local services to collaborators or the internet. It supports two modes: public sharing, which generates an HTTPS URL anyone can access, and private sharing, which creates a token-based connection that never produces a public endpoint. The security layer is OpenZiti, an open-source zero-trust networking platform, which means traffic is routed through an encrypted overlay network rather than directly through the public internet.

Problems with traditional tunneling tools

Tools like ngrok make a local service publicly accessible by forwarding traffic from a public URL to a local port. This is fast for webhooks and quick demos, but comes with practical and security tradeoffs.

Ephemeral URLs are regenerated each session on free tiers, requiring webhook URLs, documentation links, and anything else referencing that endpoint to be updated every time.

Session limits close free tunnels after a period of inactivity, which is disruptive during long debugging sessions.

Request rate limits on free plans can be hit quickly when testing APIs or serving content.

Browser warnings appear for users visiting an ngrok tunnel for the first time, adding friction to client demos.

Standard ngrok terminal session showing the generated public URL and connection status

The ngrok warning page that users see before accessing a tunneled site

Beyond usability, any public tunnel exposes a development machine to automated scanners and bots that continuously probe public URLs for vulnerabilities. For a service with database access or sensitive business logic, this is an unnecessary risk.

How zrok's zero-trust model works

zrok is built on OpenZiti, which creates a private overlay network rather than forwarding a public port.

Graphic indicating that zrok has "OpenZiti Baked In" highlighting the foundational technology

When you share something privately with zrok, no public endpoint is created. The connection exists only between authenticated participants in the overlay network. Traffic does not touch the public internet unless you explicitly choose a public share. This reduces the attack surface to zero for private shares: there is no URL to scan, no public port to probe.

Public and private sharing

zrok homepage featuring its astronaut mascot and simple command-line examples

Public sharing generates an HTTPS URL that forwards to your local service. This is appropriate for webhook testing with services like GitHub, Stripe, or Twilio, and for demos where the recipient does not have zrok installed.

Private sharing provides a share token instead of a URL. The recipient uses their own zrok client to create a local connection to your share. They access your service at a localhost address on their machine, which is proxied through the encrypted overlay to your service. No public endpoint is created at any point.

Diagram illustrating the private sharing workflow with a secure tunnel through the OpenZiti cloud between two private networks

The private model works as follows: you share a service and receive a token, you send that token through a secure channel to a trusted collaborator, they run zrok access private <token> on their machine, and a local port on their machine proxies to your service through the overlay network. No one else can access the connection.

Installation and setup

Installing the binary

On macOS with Homebrew:

 
brew install zrok

On Linux:

 
bash -c "$(curl -sS https://zrok.io/install.sh)"

On Windows with Scoop:

 
scoop bucket add zrok https://github.com/openziti/zrok-scoop.git
 
scoop install zrok

Verify the installation:

 
zrok version

Creating an account

Register with the free zrok.io service:

 
zrok invite

Enter an email address when prompted. A verification email arrives with a link to activate the account.

Enabling the environment

The verification page displays an enable command containing a unique token. Copy and run it:

 
zrok enable LgVx0ZAL99Kx

The zrok enable command being executed in the terminal showing the successful confirmation message

This stores the environment identity on the local machine. It only needs to be done once per device.

Sharing a local service

The following examples assume a service is running at http://localhost:3000.

Public share

 
zrok share public http://localhost:3000

zrok outputs a public HTTPS URL such as https://sfnblbt17596.shares.zrok.io. Anyone with that URL can access the service. Press Ctrl+C to stop the share.

Private share

 
zrok share private http://localhost:3000

Instead of a URL, zrok outputs a share token such as d6zu50wi2cm8. Send this token to the collaborator through a secure channel.

On the recipient's machine (with zrok installed and enabled):

 
zrok access private d6zu50wi2cm8

Recipient's terminal showing the zrok access private command with the unique share token

Their terminal shows a local proxy address such as http://127.0.0.1:9191 -> d6zu50wi2cm8. Opening http://127.0.0.1:9191 in their browser connects them to your local service through the encrypted overlay. No public URL exists at any point.

Final thoughts

The private sharing mode is the most significant differentiator from ngrok and similar tools. For collaboration on work-in-progress code, API endpoints with sensitive logic, or anything that should not be publicly accessible, private shares eliminate the risk entirely rather than relying on obscurity.

zrok is also self-hostable. If you need full control over the infrastructure rather than using the zrok.io public service, the project's documentation covers deploying your own instance.

The project is available at github.com/openziti/zrok and documentation at docs.zrok.io.

Got an article suggestion? Let us know
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.