[go: up one dir, main page]

Skip to main content
NewIntroducing AI Gateway

All your traffic.
One gateway.

ngrok is an all-in-one cloud networking platform that secures, transforms, and routes your traffic to services running anywhere.

Trusted by teams across the globe

  • Calendly
  • Cyera
  • Databricks
  • GitHub
  • Grafana
  • Harvey
  • Hugging Face
  • Mercor
  • Microsoft
  • Okta
  • Open AI
  • Perplexity
  • Ramp
  • Schneider Electric
  • Twilio
  • Vercel
  • Windsurf
  • Zoom
Decoration

Try ngrok by sharing a local app. Right now.

$ docker pull ngrok/ngrok
Download and setup instructions
Decoration
Decoration

Okay, but how does it work?

Connect anything with Endpoints, Traffic Policy, and Secure Tunnels.

Decoration
Endpoints & Traffic Policy

Route, transform, and authenticate your traffic.

No more cryptic nginx configs or Lua plugins. Everything is a URL with traffic rules you attach. Compose them together and offload processing to ngrok’s cloud gateway.

Fig. 1 – Traffic flows through
Endpoints & Traffic Policy

Take action at any phase in the request lifecycle.

Traffic Policy is an expressive CEL-based rules system. When a request hits different phases of its lifecycle, ngrok executes each rule sequentially.

Fig. 2 – Traffic policy examples
1on_http_request:2  # send requests with the /api path prefix to the api service3  - expressions:4      # conditions are CEL expressions, see https://cel.dev5      - req.url.path.startsWith('/api')6    actions:7      - type: forward-internal8        config:9          url: https://api.internal10 11  # route dynamically based on a header using CEL interpolation12  - actions:13      - type: forward-internal14        config:15          url: https://${req.headers('X-Custom-Header')}.internal

Even more ways to control and transform your traffic

Explore actions
Mutual TLS
OAuth + OIDC
Basic Auth
URL rewrite + redirects
Modify headers
Custom response
IP restrictions
Webhook verification

Stop cobbling your infrastructure together.

Security, performance, and resiliency built in by default.

Secure Tunnels

Connect to services anywhere, no firewall changes required.

Install a lightweight agent to deliver traffic to any service through a secure tunnel.

Fig. 3 – Anatomy of a secure tunnel
Environment Agnostic

Run your services in any environment

Because your services are connected to ngrok with secure tunnels, they can be deployed anywhere. If it listens on a port and is connected to the internet, ngrok can deliver traffic to it.

ngrok secure tunnels connecting services across cloud, on-premise, and edge environments
Zero Open Ports

Close every single inbound port

Attackers can't skirt a secure tunnel to scan or attack your origin servers, which means you whittle down your surface area and remove an entire class of attack vectors.

Zero open ports: ngrok secure tunnel blocking inbound port scanning and attack vectors
Least Privileged Access

Precise network access, not risky customer VPNs

Drop the ngrok agent into your customers' networks and tightly scope your access to just the APIs and databases you need. Not their whole subnet.

ngrok agent providing least-privileged API and database access to customer networks without a VPN
Native SDKs

import "ngrok"

Don't want to package and babysit an agent sidecar? Embed secure tunnels directly into your code with a native agent SDK.

ngrok agent SDK embedded natively in Python, Go, Java, and Node.js application code
More about secure tunnels

Join millions of developers routing billions of requests every day.

Scott Motte
@motdotla

ngrok is so effing amazing

Ihor Leshko
Director of Engineering

ngrok opened the door for Databricks to rapidly onboard big enterprise customers with comprehensive security much less operational complexity.

Databricks
Kevin Simper
@kevinsimper

I wouldn't know how to work without ngrok.

Lyzi Diamond
@lyzidiamond

OMG life changer. I can't imagine how I lived without ngrok.

Wesley Gorman
Senior Director, Engineering, Zendesk

ngrok has been super user friendly, works seamlessly, and never gets in our way. Today, our engineers spend less time troubleshooting proxy issues and more time building.

Zendesk
Brian Ketelsen
@bketelsen

Just used ngrok for the first time to show off a new GopherCon web layout. Wow, that's awesome.

Cassidy Williams
@cassidoo

ngrok saves me so much time during development. What a tool.

Austin Cottrell
Cloud Infrastructure Engineer

ngrok continues to wow us with great APIs and automation. Establishing secure remote connectivity with our customer's environments via REST APIs is fast and safe ... and amazing!

Copado
Steve Kinney
@stevekinney

ngrok makes the hard parts of networking feel effortless.

See more love

You're using ngrok right now.

ngrok received your request on our global network, filtered it through our WAF, applied a rate limit, routed it to our services, and delivered this web page to your browser.

Fig. 4 – ngrok.com's Traffic Policy
1on_http_request:2  # say bye to anonymous proxies3  - expressions:4      - "'proxy.anonymous' in conn.client_ip.categories"5    actions:6      - type: deny7 8  # rate limit requests by IP, unless you're a search/AI bot crawling the docs9  - expressions:10      - "!('com.openai.gptbot.ipv4' in conn.client_ip.categories || 'com.google.googlebot.ipv4' in conn.client_ip.categories)"11      - "!req.url.path.startsWith('/docs')"12    actions:13      - type: rate-limit14        config:15          algorithm: sliding_window16          bucket_key:17            - conn.client_ip18          capacity: 1234519          enforce: false20          name: Limit 12345 requests per minute per ip and user agent21          rate: 60s22 23  # rate limit violators get their connection closed instead of 429 errors24  - expressions:25      - actions.ngrok.rate_limit.limited26    actions:27      - type: close-connection28 29  # this is our WAF, dawg30  - actions:31      - type: owasp-crs-request32        config:33          exclude_rule_ids:34            - 93226035          on_error: continue36          process_body: true37 38  # log all WAF decisions in our observability platform and then deny anomalous requests39  - expressions:40      - actions.ngrok.owasp_crs_request.decision == 'deny'41    actions:42      - type: log43        config:44          metadata:45            action: waf deny46            anomaly_score: ${actions.ngrok.owasp_crs_request.anomaly_score}47            first_matched_data: ${actions.ngrok.owasp_crs_request.matched_rules[0].data}48            first_matched_id: ${actions.ngrok.owasp_crs_request.matched_rules[0].id}49            first_matched_message: ${actions.ngrok.owasp_crs_request.matched_rules[0].message}50            first_matched_severity: ${actions.ngrok.owasp_crs_request.matched_rules[0].severity}51            ngrok_error_message: ${actions.ngrok.owasp_crs_request.error.message}52            phase: request53      - type: deny54 55  # block countries to comply with legal requirements56  - expressions:57      - conn.geo.country_code in ['ABC', 'DEF', 'XYZ']58    actions:59      - type: deny60 61  # "we're hiring" easter egg for the curious developer62  - actions:63      - type: add-headers64        config:65          headers:66            x-ngrok-we-are-hiring: https://ngrok.com/careers67 68  # add a custom security.txt file without storing it in s3 or something69  - expressions:70      - req.url.uri.contains('/.well-known/security.txt')71    actions:72      - type: custom-response73        config:74          content: |+75            Contact: mailto:security@ngrok.com76            Canonical: https://ngrok.com/.well-known/security.txt77            Policy: https://ngrok.com/security/disclosure-and-reward-program78            Hiring: https://ngrok.com/careers79            Preferred-Languages: en80            Expires: 2026-11-01T00:00:00Z81          headers:82            Content-Type: text/plain; charset=utf-883          status_code: 20084 85  # sugar URL for invites to our discord community (come say hi!)86  - expressions:87      - req.url.path.startsWith('/discord')88    actions:89      - type: redirect90        config:91          to: https://discord.com/invite/6r7rdGX9fr92 93  # redirect legacy /downloads path to /download94  - actions:95      - type: redirect96        config:97          from: https://ngrok.com/downloads(/|$)(.*)98          status_code: 30199          to: https://ngrok.com/download/$2100 101  # redirect legacy blog path+slug102  - expressions:103      - req.url.path.startsWith('/blog-post')104    actions:105      - type: redirect106        config:107          from: ^(https?://[^/]+)/blog-post/(.*)$108          status_code: 301109          to: $1/blog/$2110 111  # handle /docs by forwarding traffic to our docs hosted in s3112  - expressions:113      - req.url.path.startsWith('/docs')114    actions:115      - type: forward-external116        config:117          url: https://ngrok.docs-provider.com118 119  # handle /blog and asset paths by forwarding traffic to an external provider120  # sorry, we gotta be a little cheeky with these121  - expressions:122      - '["/__blog-manifest","/blog-assets","/blog"].exists(p,req.url.path.startsWith(p))'123    actions:124      - type: forward-external125        config:126          url: https://blog.deployment-provider.com127 128  # handle /, /download, /pricing/, and other paths by forwarding to the same provider, different deployment129  - expressions:130      - '["/__manifest","/assets","/download","/pricing","/schemas"].exists(p,req.url.path.startsWith(p))'131    actions:132      - type: forward-external133        config:134          url: https://frontend.deployment-provider.com135 136  # legacy website paths forward to cms137  - actions:138      - type: url-rewrite139        config:140          from: /(.+)/$141          to: /$1142      - type: forward-external143        config:144          url: https://ngrok.cms-provider.com145 146on_http_response:147  # run waf on all responses148  - actions:149      - type: owasp-crs-response150        config:151          on_error: continue152          process_body: true153 154  # as before, log all those WAF decisions and deny responses155  - expressions:156      - actions.ngrok.owasp_crs_response.decision == 'deny'157    actions:158      - type: log159        config:160          metadata:161            action: waf deny162            anomaly_score: ${actions.ngrok.owasp_crs_response.anomaly_score}163            first_matched_data: ${actions.ngrok.owasp_crs_response.matched_rules[0].data}164            first_matched_id: ${actions.ngrok.owasp_crs_response.matched_rules[0].id}165            first_matched_message: ${actions.ngrok.owasp_crs_response.matched_rules[0].message}166            first_matched_severity: ${actions.ngrok.owasp_crs_response.matched_rules[0].severity}167            ngrok_error_message: ${actions.ngrok.owasp_crs_response.error.message}168            phase: response169      - type: custom-response170        config:171          content: 403 Forbidden172          headers:173            Content-Type: text/plain; charset=utf-8174          status_code: 403
Decoration

You read the whole page. What are you waiting for?

No upfront costs. No contact sales. Pay only for what you use.

Decoration