Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ngrok.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Traffic Policy lets you configure access controls once and enforce them on every device in your fleet. No firmware pushes, OTA updates, or truck rolls required to update security rules. Use Traffic Policy to:
  • Authenticate and restrict traffic before it reaches your devices. Require JWTs, OAuth, or specific IP ranges so only authorized traffic can reach your fleet, and rate limit noisy consumers before they overwhelm a device.
  • Access services, not entire devices. Unlike VPNs, ngrok exposes exactly the service each consumer needs and not a single port or process more. Use internal endpoints combined with Cloud Endpoints to control which services are accessible and to whom, and to forward and load balance traffic across them.
  • Update policy without touching devices. When a new security requirement comes in, update one Traffic Policy and the change applies across your entire fleet immediately. No need to push updates to individual devices.

Restrict access by IP

Limit access to specific IP addresses or CIDR ranges: The following Traffic Policy configuration demonstrates how to restrict access to specific IP addresses using the restrict-ips action.

Example Traffic Policy document

on_tcp_connect:
  - actions:
      - type: restrict-ips
        config:
          enforce: true
          allow:
            - 1.1.1.1/32
          deny:
            - 110.0.0.0/8
This configuration will ensure that only requests from the IP 1.1.1.1 are allowed, while requests from the IP 110.0.0.0 are denied.

Example request

If the request comes from an allowed IP, the response will proceed as normal. If the request comes from a denied IP, the connection will be closed:
$ telnet 5.tcp.ngrok.io 22984

Trying...
Connected to 5.tcp.ngrok.io.
Connection closed by foreign host.
See the restrict-ips action reference for details.

JWT validation

Require a valid JWT token on every request: The following Traffic Policy configuration is an example configuration of the jwt-validation action. For a more real-world example, check out the Auth0 guide.

Example Traffic Policy document

on_http_request:
  - actions:
      - type: jwt-validation
        config:
          issuer:
            allow_list:
              - value: https://example.com/issuer
          audience:
            allow_list:
              - value: urn:example:api
          http:
            tokens:
              - type: access_token
                method: header
                name: Authorization
                prefix: 'Bearer '
              - type: it+jwt
                method: body
                name: _id_token
          jws:
            allowed_algorithms:
              - RS256
              - ES256
            keys:
              sources:
                additional_jkus:
                  - https://example.com/issuer/jku

Example request

$ curl --request GET \
  --url http://example-api.ngrok.app/ \
  --header 'authorization: Bearer <VALID-JWT>'
HTTP/2 200 OK
content-type: text/html

...
In this example, a request is sent to the API with a valid JWT token in the Authorization header with the Bearer prefix and getting back a 200 OK response. See the jwt-validation action reference for full configuration options.

OAuth

Require login via Google, GitHub, Microsoft, or other providers:
on_http_request:
  - actions:
      - type: oauth
        config:
          provider: google
          client_id: '{your oauth client id}'
          client_secret: '{your oauth client secret}'
          scopes:
            - https://www.googleapis.com/auth/userinfo.profile
            - https://www.googleapis.com/auth/userinfo.email
See the OAuth action reference for full configuration options.

Rate limit by host header

Prevent a misbehaving integrator, customer app, or internal service from overwhelming your devices: The following Traffic Policy configuration demonstrates how to use the rate-limit action to rate limit all incoming requests by the Host header.

Example Traffic Policy document

on_http_request:
  - actions:
      - type: rate-limit
        config:
          name: Only allow 30 requests per minute
          algorithm: sliding_window
          capacity: 30
          rate: 60s
          bucket_key:
            - 'hasReqHeader(''host'') ? getReqHeader(''host'')[0] : ''unknown'''
For this example, assume that ngrok is pointing at the upstream service https://httpbin.org.

Example request

$ curl https://httpbin.ngrok.app/get
HTTP/2 429
retry-after: 24
In this example, a connection attempt to httpbin.ngrok.app using the curl command returns a 429 status code with a retry-after header indicating the number of seconds to wait before retrying the request. See the rate-limit action reference for details.

Forward traffic to internal services

Route public traffic to internal endpoints so devices are never directly exposed. This example configuration will set up a public endpoint (forward-internal-example.ngrok.app) forwarding all traffic it receives to a internal endpoint (example.internal) that forwards the request to port 80 on your local machine. Since it is forwarding all traffic to the internal endpoint, no traffic will be sent to 8080 which is the upstream port for the public endpoint.

Example Traffic Policy document

on_http_request:
  - actions:
      - type: forward-internal
        config:
          url: https://example.internal

Start an internal endpoint

ngrok http 80 --url example.internal

Start public endpoint with Traffic Policy

ngrok http 8080 --url forward-internal-example.ngrok.app --traffic-policy-file /path/to/policy.yml

Example request

$ curl https://forward-internal-example.ngrok.app -v
 ...
> GET / HTTP/2
> Host: forward-internal-example.ngrok.app
> User-Agent: curl/[version]
> Accept: */*
...
This request will be forwarded to the internal endpoint https://example.internal which will then forward the request to port 80 on your local machine.
GET / HTTP/1.1
Host: forward-internal-example.ngrok.app
User-Agent: curl/[version]
Accept: */*
X-Forwarded-For: [ngrok IP]
X-Forwarded-Host: forward-internal-example.ngrok.app
X-Forwarded-Proto: https
Accept-Encoding: gzip
See the forward-internal action reference for details.

Next steps