One API gateway. Anywhere your services run.
ngrok collapses routing, WAF, observability, failover, and auth into one gateway. Plus, it works the exact same within your VPC, across multiple clouds, on K8s clusters, or from inside a customer’s network.
One agent.
Every environment.
The agent connects outbound on port 443, which means no inbound ports, DNS changes, or per-environment gateway. Traffic flows through ngrok’s cloud and out to wherever your services live.
ngrok is your global entry point to anywhere your APIs run. The same agent runs on a laptop, a VM, a Raspberry Pi, an EC2 box, or a Kubernetes cluster.
Block attacks, rate-limit abusers, and authenticate every request at our cloud. Good traffic goes where it should. Bad traffic never reaches your VPC.
One install, one command, anywhere. Agents create unique URLs for each service that’s accessible only through the front door you control in ngrok’s cloud.
Close every port. Because the agent connects outbound, attackers have no way to poke at your origin servers, which remain fully locked down.
# In front of your API servicengrok http 3000 --url https://api.internal# In front of your app servicengrok http 8080 --url https://app.internalBuild on an expressive rules system. No more cryptic nginx configs or Lua plugins. Instead, compose rules across teams and offload processing to ngrok’s cloud.
Route to new services, simply. Append a new forward-internal rule to your existing policy and you’re off, no matter where the service runs.
on_http_request: # Block anonymous proxies, Tor exit nodes, and threat lists - expressions: - >- 'proxy.anonymous' in conn.client_ip.categories || 'blocklist.org.firehol.level_1' in conn.client_ip.categories actions: - type: deny # Rate-limit abusers per client IP - actions: - type: rate-limit config: name: per-ip algorithm: sliding_window capacity: 100 rate: 60s bucket_key: - conn.client_ip # Block OWASP top 10 attacks inbound to your apps - actions: - type: owasp-crs-request config: on_error: deny # Add security and tracing headers on the way in - actions: - type: add-headers config: headers: x-request-id: ${req.id} strict-transport-security: max-age=31536000 # Route to the internal endpoints you created with the agent - expressions: - req.url.path.startsWith('/v1/') actions: - type: forward-internal config: url: https://api.internal - actions: - type: forward-internal config: url: https://app.internal on_http_response: # Block OWASP top 10 attacks outbound from your apps - actions: - type: owasp-crs-response config: on_error: deny # Compress responses on the way out - actions: - type: compress-responseWhy ngrok?
Stop running five tools to do one job. Routing, WAF, rate limiting, auth, and certs all live in one gateway.
Add modern controls to APIs you can’t rewrite. Enforce JWT validation, OAuth, rate limits, and IP rules at our network.
Works the same everywhere your APIs do. AWS, Azure, on-prem, K8s, and customer networks behind one gateway.
Platform owns the front door, teams own their routes. Layered policy that scales from day one.
Self-service from $20/month.
Pay only for what you use and scale as you grow.
It really can be that simple.
Bring your messy config.
Leave with something far simpler.
This is a real production nginx config from a real developer. They shed a ton of code and complexity on their way to something that's far more expressive and elegant. And yes, you can have this too.
1user www-data;2worker_processes auto;3pid /run/nginx.pid;4include /etc/nginx/modules-enabled/*.conf;5worker_rlimit_nofile 65536;6 7events {8 worker_connections 4096;9 multi_accept on;10 use epoll;11 accept_mutex off;12}13 14http {15 # Anti-indexing and security headers16 add_header X-Robots-Tag "noindex, nofollow, noarchive, nosnippet" always;17 add_header X-Frame-Options "DENY" always;18 add_header X-Environment "production" always;19 20 # Basic settings - production optimized21 sendfile on;22 tcp_nopush on;23 tcp_nodelay on;24 25 # Hash table sizes26 types_hash_max_size 4096;27 types_hash_bucket_size 128;28 server_names_hash_bucket_size 128;29 server_names_hash_max_size 2048;30 31 server_tokens off;32 33 # Memory optimizations34 open_file_cache max=10000 inactive=20s;35 open_file_cache_valid 30s;36 open_file_cache_min_uses 2;37 open_file_cache_errors on;38 39 # Client buffers and timeouts40 client_body_buffer_size 128k;41 client_header_buffer_size 4k;42 client_max_body_size 100m;43 large_client_header_buffers 8 32k;44 client_body_timeout 60;45 client_header_timeout 60;46 keepalive_timeout 120;47 send_timeout 60;48 include /etc/nginx/mime.types;49 default_type application/octet-stream;50 51 # Enhanced logging format52 log_format main '$remote_addr - $remote_user [$time_local] "$request" '53 '$status $body_bytes_sent "$http_referer" '54 '"$http_user_agent" "$http_x_forwarded_for" '55 'rt=$request_time uct="$upstream_connect_time" '56 'uht="$upstream_header_time" urt="$upstream_response_time"';57 access_log /var/log/nginx/access.log main buffer=512k flush=1m;58 error_log /var/log/nginx/error.log warn;59 60 # Gzip compression61 gzip on;62 gzip_comp_level 6;63 gzip_min_length 1024;64 gzip_proxied any;65 gzip_vary on;66 gzip_disable "msie6";67 gzip_types application/json application/xml text/css68 text/javascript image/svg+xml font/ttf;69 70 include /etc/nginx/conf.d/*.conf;71 include /etc/nginx/sites-enabled/*;72}73 74# /etc/nginx/sites-enabled/api.example.com75upstream backend_api {76 server 127.0.0.1:3000;77 keepalive 32;78}79 80server {81 server_name api.example.com;82 listen 443 ssl http2;83 84 # TLS managed by Certbot85 ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;86 ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;87 include /etc/letsencrypt/options-ssl-nginx.conf;88 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;89 ssl_stapling on;90 ssl_stapling_verify on;91 92 # Security headers93 add_header Strict-Transport-Security "max-age=31536000; preload" always;94 add_header X-Content-Type-Options nosniff always;95 add_header X-XSS-Protection "1; mode=block" always;96 add_header Referrer-Policy "strict-origin-when-cross-origin" always;97 98 # Main proxy99 location / {100 proxy_pass http://backend_api;101 proxy_set_header Host $host;102 proxy_set_header X-Real-IP $remote_addr;103 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;104 proxy_set_header X-Forwarded-Proto $scheme;105 proxy_http_version 1.1;106 proxy_set_header Upgrade $http_upgrade;107 proxy_set_header Connection "upgrade";108 109 # Proxy timeouts and buffering110 proxy_connect_timeout 120s;111 proxy_send_timeout 180s;112 proxy_read_timeout 300s;113 proxy_buffering on;114 proxy_buffer_size 4k;115 proxy_buffers 8 4k;116 proxy_busy_buffers_size 8k;117 118 # Upstream resilience119 proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;120 proxy_next_upstream_timeout 120s;121 proxy_next_upstream_tries 3;122 }123 124 # Static asset caching125 location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {126 expires 1y;127 add_header Cache-Control "public, immutable";128 proxy_pass http://backend_api;129 }130 131 # Health check132 location /health {133 access_log off;134 proxy_pass http://backend_api;135 proxy_connect_timeout 10s;136 proxy_send_timeout 10s;137 proxy_read_timeout 10s;138 }139 140 # Block hidden files141 location ~ /\. {142 deny all;143 access_log off;144 log_not_found off;145 }146}147 148# HTTP -> HTTPS redirect (managed by Certbot)149server {150 if ($host = api.example.com) {151 return 301 https://$host$request_uri;152 }153 listen 80;154 server_name api.example.com;155 return 404;156}Wherever your APIs live,
ngrok meets them there.
Cloud-provider gateways stop at their own cloud. ngrok installs and runs the exact same way in every environment to put one hostname in front of your services wherever they live.
Go multicloud without per-cloud gateways
The agent runs in each cloud and connects outbound. One hostname spans AWS, Azure, and GCP. Endpoint Pools route traffic by region and fail over when a cloud goes down. No DNS headaches or managing a daisy chain of load balancers.
Ingress to multiple clusters
Each cluster runs the ngrok Operator and connects outbound. Route north-south traffic across all of them under one hostname and scale up as easily as adding more replicas of a pod.
Add connectivity to private and on-prem services
The ngrok agent connects outbound from any network and on any hardware, so services once reachable only through a VPN-esque kludge open up to specific identities.
Reach into customer networks, too
Embed the agent in software you ship. Each customer install becomes a routable origin under one gateway, whether you have one install or ten thousand.
Everything else your gateway needs to run at scale.
Watch and export every request
Traffic Inspector replays every request in the dashboard. Export events and metrics to Datadog, CloudWatch, S3, or any JSON-ingesting platform.
Load balance with one URL
Point multiple agents at the same URL to create an Endpoint Pool. ngrok load-balances, fails over to healthy backends, and routes by region.
Scale it all with APIs and K8s
Use your favorite IaC tooling to provision ngrok primitives. Every endpoint, route, and policy has an API, so you can wire it all up quickly and declaratively.
Managed end-to-end TLS
ngrok provisions and renews certs for every endpoint—no PEM files, no renewal jobs. Terminate TLS at the agent or your upstream to route ciphertext only.
Pin traffic to specific regions
Pick which ngrok regions relay traffic per domain or endpoint to meet data residency requirements.
All the boxes you need to check
Platform owns the front door.
Service teams own their routes.
Most gateways force you to choose between centralized control and team velocity. ngrok lets the right team manage the right policy and composes it all together on our cloud.
on_http_request: # Block anonymous proxies and Tor exit nodes - expressions: - "'proxy.anonymous' in conn.client_ip.categories" actions: - type: deny # Rate-limit abusers per client IP - actions: - type: rate-limit config: name: per-ip algorithm: sliding_window capacity: 100 rate: 60s bucket_key: - conn.client_ip # Block OWASP top 10 attacks at ngrok's cloud - actions: - type: owasp-crs-request config: on_error: deny # ... and a whole bunch moreon_http_request: # Rewrite legacy /v1/* paths to /v2/* - expressions: - req.url.path.startsWith('/v1/') actions: - type: url-rewrite config: from: ^/v1/(.*)$ to: /v2/$1 # Ship a structured event for every request # to the observability pipeline - actions: - type: log config: metadata: team: api-platform request_id: ${req.id} method: ${req.method} path: ${req.url.path} client_ip: ${conn.client_ip} country: ${conn.geo.country_code} user_agent: ${req.user_agent.name} is_bot: ${req.user_agent.is_bot}Stop running five tools. Start running one gateway.
Free to start. Three minutes from signup to first request.