I got tired of configuring Cloudflare Zero Trust manually, so I built a 15s CLI wrapper.
Every time I wanted to expose a new local service (like Grafana or a dev API) securely, the routine was always the same:
Open Cloudflare Dashboard.
Create a new Tunnel.
Configure Ingress rules.
Add a DNS CNAME record.
Switch to the Zero Trust panel.
Create an Access Application.
Set up an Access Policy to restrict access to my email.
It’s an amazing, enterprise-grade security stack, but doing this manually for the 10th time just to test something is an absolute UX nightmare.
I wanted something as simple as ngrok, but with Cloudflare's Zero Trust protection under the hood. Since I couldn't find a lightweight tool that does exactly this, I wrote zt in Go.
How it works
Now, when I need to share or expose a local service, I just run:
zt up grafana 3000
In about 15 seconds, it automatically handles the whole chain:
Creates the Cloudflare Tunnel.
Sets up DNS and Ingress.
Locks it behind Cloudflare Access (asks for email OTP by default).
Fires up cloudflared in the background and saves the state locally.
If I need it to be completely public (like an webhook endpoint), I just pass a flag: zt up api 8080 --public. If I want to share it with specific colleagues: --allow mail@example.com
When I'm done, zt down grafana wipes everything clean and stops the process.
The Stack
It’s a single binary written in Go, using the official Cloudflare API package. Configuration and state are kept locally in ~/.zt-config.json and ~/.zt-state.json (secured with 0600 permissions).
I’ve been using it daily in my home lab and dev environment, and it has saved me hours of clicking through web UIs.
The project is completely open-source (MIT). If you're managing self-hosted apps or often need to expose local ports securely, feel free to check it out, open an issue, or drop a star!
casablanque-code
/
cfzt
cloudflare tunnel zero trust UX
zt — Zero Trust tunnel manager
One command to expose a local service through Cloudflare Zero Trust.
zt up grafana 3000
# → https://grafana.yourdomain.com (ZT-protected, running in 15s)
What it does
zt up <name> <port> automatically:
- Creates a Cloudflare Tunnel
- Configures ingress rules
- Creates a CNAME DNS record
- Creates a Zero Trust Access application
- Starts
cloudflaredin the background - Saves state locally
zt down <name> reverses all of the above.
Prerequisites
- A domain on Cloudflare
-
cloudflaredinstalled and in PATH - A Cloudflare API token with the following permissions:
Account / Cloudflare Tunnel / EditZone / DNS / EditAccount / Access: Apps and Policies / Edit
Creating the API token
- Cloudflare dashboard → My Profile → API Tokens → Create Token
- Use Custom token, add the permissions above
- Set Account Resources → your account
- Set Zone Resources → your domain
Install
Option A — go install
go install…
Top comments (0)