You've got a service running on localhost:8080 and something outside your machine needs to reach it — a phone on cellular data, a partner's server firing callbacks, or a frontend you deployed to Vercel that's still pointed at your dev box. To expose a local API to the internet, you need a public HTTPS endpoint that forwards to that port, and — because it's an API and not a static demo — you probably want auth, rate limiting, and a way to see the traffic. This walks through doing all of that with a single agent, without touching your router or firewall.
Why expose a local API (and why port-forwarding is the wrong tool)
Three situations come up constantly during development:
- Mobile device testing. Your iOS or Android build can't hit
localhost— that resolves to the phone itself. You need a real hostname over HTTPS, because App Transport Security and modern network stacks refuse plaintext by default. - Third-party callbacks. A payment provider, an OAuth flow, or a partner's webhook needs to POST back to your API. Their servers can't route to your laptop, and you can't finish the integration without a reachable URL.
- A deployed frontend hitting your local server. The UI lives on a staging URL but the backend you're actively changing is on your machine. You want the deployed app to talk to your live code without a redeploy per change.
The instinct is to forward a port on your router. Don't. Port-forwarding opens an inbound hole in your network, exposes your machine's real IP, and hands you the job of provisioning a certificate and terminating TLS yourself. On a laptop that moves between networks — or behind carrier-grade NAT where you don't control the router — it doesn't work at all. And it gives you a raw open port with no auth, no rate limit, and no visibility into what's hitting it.
Ngris inverts the direction. The agent makes an outbound connection to the Ngris edge; the edge hands you a public HTTPS hostname with TLS terminated there, and requests forward back down that same connection to your local port. Nothing is opened on your network, and your machine's IP stays private. If you just want the mechanics of a public URL, see exposing localhost to the internet; this post is about putting a real gateway in front of an API.
One command: public HTTPS in front of your port
Install the agent for your platform:
# macOS
brew install ngris
# Linux
curl -fsSL https://ngris.com/install.sh | sh
# Windows
winget install NgrisAuthenticate once with the token from your dashboard, then point the agent at the port your API listens on:
# one-time auth
ngris auth --token <token>
# expose the API on port 8080
ngris http 8080You get an HTTPS hostname immediately, serving HTTP/1.1, HTTP/2, and HTTP/3 (QUIC) at the edge. That hostname is ephemeral — it lives while the agent runs. For mobile testing or a webhook you register with a partner, a URL that changes on every restart is a nuisance, so reserve a stable one:
# stable hostname across restarts
ngris http 8080 --url app.ngris.comNow your deployed frontend's API_BASE_URL, your phone's build config, and the partner's callback registration all point at one address that survives you closing your laptop. The free plan gives you 5 endpoints with no credit card. If a partner needs to allowlist your outbound traffic, static egress IPs give you a stable outbound address to hand them.
Lock it down: auth, rate limits, and a WAF
A public API URL is a public attack surface. Because Ngris is a gateway and not just a tunnel, you attach security as ordered traffic-policy rules that run at the edge before a request ever reaches your local process. There are 23 rule types across ordered phases (WAF, JWT, mTLS, rate limits, transforms), so you compose exactly the front door you need:
- JWT validation. Add a JWT rule and the edge rejects unauthenticated requests before they touch your code — so your local dev server never has to see the internet's noise.
- Rate limiting. Cap requests per client so a misbehaving mobile build or a hammering integration test can't overwhelm your machine.
- A web application firewall. The Coraza-powered WAF attaches as a single traffic-policy rule. It runs in detect-by-default mode so you can watch what it would catch, then flip it to block once you trust it.
- mTLS. For machine-to-machine partner integrations, require a client certificate so only holders of the right cert can call the endpoint.
If the API is internal — an admin backend, a staging service that shouldn't be world-readable — you don't want a shared secret you'll paste into Slack. Put identity-aware access in front of it: SSO/OIDC through Google, GitHub, or Okta with unified RBAC, so only people in your org (or a specific role) reach the API, with no VPN to run. Every rule above is composable — WAF plus JWT plus a rate limit is three rules in one policy, evaluated in phase order at the edge.
See every call: Traffic Inspector and Replay
The hardest part of an API integration is the request you can't see. A webhook returns 400 and the provider's dashboard tells you nothing; a mobile client sends a body that doesn't match what you expected. The live Traffic Inspector shows every request through your endpoint — filter by host, path, status, method — with full headers and bodies, so you read exactly what arrived instead of guessing from a log line.
Then use Replay to re-send the exact captured request. When a callback fails, you don't ask the partner to fire it again and you don't hand-craft a curl command from memory — you replay the real payload against your local server after you've patched the handler, and repeat until it's green. You can also replay a captured request to a different environment to confirm a fix behaves the same way in staging.
Iris, the AI built into Ngris, sits alongside this: describe a firewall or rate-limit policy in plain English and it drafts the traffic-policy config for you to review before saving, answers configuration questions in the dashboard and docs, and surfaces things like certificate expiry or weak security posture proactively so you're not the last to know.
A gateway, not just a tunnel
The distinction matters. A plain tunnel gives you a URL and gets out of the way — you're on your own for auth, abuse protection, and debugging. Ngris terminates TLS, runs your WAF, validates JWTs, enforces rate limits, gates access by identity, and records every call for inspection and replay — all at the edge, in front of an API that never leaves your machine. The same pieces move to production unchanged: custom domains with automatic TLS via a CNAME to cname.ngris.io, static egress IPs, and a Kubernetes operator and Gateway API for when the local server becomes a real deployment.
Start with one command against your dev port, add the rules you need one at a time, and watch the traffic as it flows. The free plan is 5 endpoints and no credit card — run ngris http 8080 and put a real gateway in front of your API in the next minute.