February 21, 2024
|
5
min read

Introducing ngrok's Traffic Policy module

Nijiko Yonskai

We are excited to introduce the Traffic Policy module, now available in early access.

For over 5 million developers, ngrok has been the trusted solution for testing webhooks, collaborating on developer previews, and validating mobile backends. However, as enterprises scale and move towards production, a common challenge emerges. Having to move to the Cloud Edge requires rewriting configuration created with the agent and SDKs, leading to frustration and inconsistencies that increase the risk of misconfigurations.

This is why we built the Traffic Policy module. Currently in early access, this module provides users with a flexible and uniform approach to configuring and managing traffic across all ngrok platforms, whether it's the Cloud, API, SDKs, or Kubernetes. The Traffic Policy module lets you use Common Expression Language (CEL) and JSON or YAML to create rules for incoming or outgoing traffic. With the Traffic Policy module you can create rules from basic access restrictions to advanced logic like XSS detection.

While this is an early preview we believe this is the future of ngrok and just the beginning of a more simplified and streamlined way of handling traffic flow, setting the stage for exciting developments to come.

How does it work?

The Traffic Policy module allows you to define a Traffic Policy document, written in JSON or YAML, that contains a list of custom rules (known as Policy Rules) validated at runtime against <code>inbound</code> and <code>outbound</code> traffic alongside your existing Edge modules for HTTP, TCP, and TLS.

Policy Rule

Policy rules consist of <code>expressions</code> and an associated list of <code>actions</code> to perform on <code>inbound</code> (requests) and <code>outbound</code> (responses) traffic that match the expressions.

Expressions

Policy Rule Expressions, written in CEL, define the filter criteria for evaluating requests and responses. Expressions have access to everything: URLs, query strings, headers, cookies, geolocation and more. For example, a simple expression could look like this:

req.URL.contains('/signup') && conn.Geo.CountryCode in ['IR']

The Policy Rule Expression above checks if the request URL starts with <code>/signup</code> and the IP country code is Iran (<code>IR</code>). Checks like the one above can be useful if you want to reroute to a language specific page or block traffic from a specific country.  

If no expression exists, all defined actions in the rule will run. If an expression exists and does not match, the Traffic Policy module will evaluate the next expression available. Multiple expressions in the list will be joined together with the <code>&&</code> operator.

Actions

Policy Rule Actions are bits of business logic you can configure and apply to your traffic such as denying traffic, sending custom responses, rate limiting or rewriting URLs. 

The following actions are available today:

  • Deny Traffic (<code>deny</code>) - Protect your services by blocking HTTP or TLS requests or terminate a TCP connection.
  • JWT Verification (<code>jwt</code>) - Add JWT verification support for HTTP requests.
  • Log Metadata in Events (<code>log</code>) - Add metadata to log events for HTTP, TCP, TLS.
  • Rate Limit Traffic (<code>rate-limit</code>) - Achieve multi-tenant resiliency by ensuring fairness across all clients.
  • Rewrite URLs (<code>url-rewrite</code>) - Transform SEO friendly, customer facing URLs at runtime to the actual URL of the service.
  • Add Headers (<code>add-headers</code>) - Add headers to HTTP requests and responses.
  • Remove Headers (<code>remove-headers</code>) - Remove headers from HTTP requests and responses.

What can you create with policy rules?

You can mix and match these rules to secure your applications and optimize performance. Use parameters to construct business logic in order to handle many use cases ranging from WAF security rules, API gateway configuration, and creating maintenance pages.

Let’s take a look at some real-world examples.

Lock down specific paths using geolocation

This is an example of an inbound policy rule to deny sign up requests from Iran:

policy:
  inbound:
  - expressions:
    - req.URL.contains('/admin') && conn.Geo.CountryCode in ['IR']
    actions:
    - type: deny

Prevent unwanted access to a specific path

The following inbound policy rule can be used to deny requests from a specific IP for a specific path:

policy:
  inbound:
  - expressions:
    - req.URL.contains('/admin')
    - conn.ClientIP != '192.168.1.12'
    actions:
    - type: deny

Quickly deprecate API versions:

The following inbound policy rule can be used for returning a custom response when a specific API version is requested:

policy:
  inbound:
  - expressions:
    - '2' in req.Headers['x-api-version']
    actions:
    - type: custom-response
      config:
        status_code: 400
        content_type: application/json
        content: >
          {
            "error": {
              "message": "Version 2 of the API is no longer supported. Use Version 3 instead."
            }
          }

You can find these use-cases and more in our rule gallery. We are in the process of porting all our existing modules to this framework. Stay tuned for updates.

Unlock simplicity with CEL

Why did we choose CEL for the Traffic Policy module? ngrok is known for its simplicity - with just one command or one function call, you can bring secure connectivity from localhost to production environments effortlessly. We asked ourselves how we could extend this simplicity to the critical task of configuring traffic policies. Enter CEL. CEL is a powerful tool for logic and decision-making, enabling you to write concise expressions that evaluate data and perform actions. Here are some key benefits of using CEL: 

  • Simple and familiar: CEL syntax resembles familiar languages like C++, Go, Java, and TypeScript, making it easy to learn and use. It avoids complex programming concepts and focuses on straightforward expressions
  • Safe and secure: It restricts certain functionalities to prevent code injection and other security vulnerabilities. It can’t perform unbounded loops or recursion, ensuring predictable behavior
  • Portability: CEL expressions can be evaluated in different environments and programming languages, fostering code reuse and interoperability. 

Unlike proprietary scripting languages of appliance based application delivery infrastructure which require a steep learning curve, CEL is designed for simplicity, speed, safety, and portability. It also has tremendous expressive power - supports a wide range of data types and operators, allowing you to define complex logic. 

Get started with the Traffic Policy module

You can set up and configure the Traffic Policy module through the CLI, SDKs or directly on a Cloud Edge.

Using the ngrok CLI flag

You can pass Traffic Policy configs, written in YAML, to the ngrok CLI using the <code>--policy-file</code> flag. For example, given the following <code>policy-config.yml</code>:

inbound:
  - expressions:
      - req.URL.contains('/admin') && conn.Geo.CountryCode in ['IR']
    actions:
      - type: deny

You would run the following command:

ngrok http 80 --policy-file policy-config.yml

This would create a new endpoint that restricts access to the <code>/admin</code> path to users in Iran based on IP geolocation.

Using the ngrok CLI config file

In addition to using the ngrok CLI flags, you can apply a Traffic Policy config directly inside your ngrok config file:

tunnels:
  limit:
    proto: http
    addr: 127.0.0.1:80
    domain: my-example-domain.ngrok.app
    policy: 
      inbound:
        - expressions:
            - "req.Method != 'GET'"
          actions:
            - type: "deny"

To start your tunnels with this setup you would run the following command:

ngrok start --all

This would deny all non-GET HTTP requests to your specific endpoint at <code>my-example-domain.ngrok.app</code>.

Using the ngrok agent SDKs

You can find documentation for using the Traffic Policy module through each ngrok agent SDK under the related protocol documentation pages:

Using the ngrok API

The Traffic Policy module can be configured through the API on the following entities:

Using ngrok Cloud Edges

You can start using the Traffic Policy module starting today by navigating to or creating an Edge under the Cloud Edges via the dashboard or with the API.

For more information about available actions and their configuration check out the Traffic Policy module for the protocol you are using:

You can additionally find a list of available actions in the documentation above. 

Start shaping traffic flows effortlessly

Early access of Traffic Policy module is now available in your ngrok account. Please try it and give us feedback. You can reach us on ngrok community on Slack or at support@ngrok.com. In case you don’t yet have an account, you can sign up for one. Let us know if you run into any problems or have any questions. Reach out to us if you have an idea/request for an action.

Share this post
Nijiko Yonskai
Niji is a Senior Product Manager at ngrok helping shape ngrok user experience. Previously product at Kong and Postman. Outside of work Niji is an amateur pasta chef, early-stage investor, writer and open-source developer.
Product updates