News

Protect a tunnel with a password, a token, or an IP allowlist

Tunnels are public by default. Now you can put a gate in front of one, and it is checked at the edge, so an unwanted request never reaches your machine.

A viaduct tunnel gives a service on your machine a public HTTPS URL, and until now that URL was open: anyone who had it could reach your app. That is fine for a quick share, but not when you are demoing something private, testing a webhook you would rather strangers not hit, or leaving a tunnel up for a while. So a tunnel can now carry its own access control.

Add --basic-auth for a username and password, and visitors get the browser's login prompt:

viaduct http 3000 --basic-auth alice:secret
โœ“ tunnel live

  https://funny-otter.viaduct.sh
  โ†’ http://localhost:3000
  โ— protected ยท Basic auth

# a visitor with no credentials is turned away at the server
$ curl -s -o /dev/null -w '%{http_code}\n' https://funny-otter.viaduct.sh
401

# with the right credentials, the request reaches your app
$ curl -s -u alice:secret https://funny-otter.viaduct.sh
<h1>your app</h1>

The 401 is answered by the server. Your app only ever sees the authorised request.

Prefer a token for an API or a webhook? Use --bearer and the request must carry Authorization: Bearer <token>. Want to restrict by address instead, or as well? --allow-ip takes a single IP or a CIDR range, and you can list several by repeating the flag or comma-separating them:

viaduct http 3000 --allow-ip 203.0.113.4 --allow-ip 10.0.0.0/8

The three compose. Require a password and pin it to your office range if you like; a request has to clear every gate you set.

Checked at the edge, not on your machine

This is the part that matters. The check runs on the server, the moment a request arrives, before viaductd opens a connection back to you. An unauthorised visitor gets a clean, branded 401 or 403 and their request is dropped there. It never travels down the tunnel, so it never touches your app. Access control that only kicked in after the request reached your machine would not be worth much; this happens at the door.

Your credentials stay on your machine, too. The client sends only a hash of the password or token in the opening handshake, never the plaintext, and the server keeps nothing on disk. To keep secrets out of your shell history, set VIADUCT_BASIC_AUTH (or VIADUCT_BEARER), or put basic_auth in ~/.config/viaduct/config.toml, and pass --basic-auth alice with no password to be prompted for it.

What it is, and what it is not

This is access control for sharing a link with the right people: the right ones get in, everyone else gets a tidy "no". You can change the page they see with --auth-message and --deny-message, and the browser prompt's label with --auth-realm. It is not a shield against denial-of-service floods; that is a job for the network in front, not a tunnel flag. Being honest about the boundary is the point.

Using it

Pick whichever gate fits, and start the tunnel as usual:

viaduct http 3000 --basic-auth alice:secret

There is more in the docs, including the config-file and environment-variable options and a note for anyone running their own server without a trusted front.

Available in viaduct 1.4.0. Already installed? Run viaduct upgrade to get it.

← All news