<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax" -->

---
title: How we built the Traffic Policy module and its actions
description: Ngrok engineers explain the design behind Traffic Policy, a CEL-based system that replaced ngrok's older module-based approach to configuring middleware like...
canonical: https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: How we built the Traffic Policy module and its actions | daily.dev
og:description: Ngrok engineers explain the design behind Traffic Policy, a CEL-based system that replaced ngrok's older module-based approach to configuring middleware like...
og:url: https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax
og:image: https://api.daily.dev/og/posts/BFMcSrtax.png
og:image:alt: How we built the Traffic Policy module and its actions
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How we built the Traffic Policy module and its actions

**[ngrok Blog](https://daily.dev/sources/ngrok)** · 13 min read · 0 upvotes · 0 comments

## Summary

Ngrok engineers explain the design behind Traffic Policy, a CEL-based system that replaced ngrok's older module-based approach to configuring middleware like IP restrictions, OAuth, and compression. The piece covers why the old module system was fragmented across agents, SDKs, the Kubernetes Operator, and the API with inconsistent naming and configuration, and how Traffic Policy unifies this with expressions, phases (on_tcp_connect, on_http_request, on_http_response), and nested handler chains. It also details performance tuning of CEL environments via variable scoping, and lists actions now available (Add/Remove Headers, Compress Response, Deny, Restrict IPs, JWT Validation, Rate Limit, URL Rewrite, Redirect, Log), plus future plans for conditional action chaining and forwarding.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://ngrok.com/blog/engineering-traffic-policy>

## Questions this post answers

### What is ngrok Traffic Policy and how does it differ from ngrok's old modules system?

Traffic Policy is ngrok's unified system for conditionally shaping requests and responses using the Common Expression Language (CEL), replacing the older per-form-factor module system. Unlike modules, which could only be toggled on or off per endpoint with inconsistent configuration across the CLI agent, SDKs, Kubernetes Operator, and API, Traffic Policy applies conditional rules based on paths, headers, or origin across three phases: on_tcp_connect, on_http_request, and on_http_response.

_Developers evaluating traffic-shaping approaches can track ngrok's Traffic Policy evolution on daily.dev._

### How does ngrok scope CEL environment variables for performance in Traffic Policy?

Ngrok compiles each CEL expression into an AST and applies a custom decorator called accessedVarTracker that records only the variables actually referenced in that expression. At runtime, only those tracked variables are fetched before evaluation, avoiding the overhead of resolving more than 100 available connection variables for every request or response passing through the handler chain.

_Engineers optimizing rule-evaluation pipelines can follow deep dives like this on daily.dev._

### What actions are available in ngrok Traffic Policy for shaping HTTP, TLS, and TCP traffic?

Ngrok Traffic Policy actions include Add Headers, Remove Headers, Compress Response, Deny, Restrict IPs, JWT Validation, Rate Limit, URL Rewrite, Redirect, and Log, covering HTTP, TLS, and TCP protocols depending on the action. These migrated existing module functionality (like IP restriction) while adding new capabilities such as JWT validation and rate limiting that were never available as standalone modules.

_Teams configuring API gateway rules can keep up with new traffic-shaping actions via daily.dev._

---

Tags: [#devtools](https://daily.dev/tags/devtools), [#networking](https://daily.dev/tags/networking), [#api-gateway](https://daily.dev/tags/api-gateway)

[View this post on daily.dev](https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"How we built the Traffic Policy module and its actions","url":"https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax"},"datePublished":"2026-08-23T07:20:29.824Z","dateModified":"2026-08-23T07:24:57.238Z","description":"Ngrok engineers explain the design behind Traffic Policy, a CEL-based system that replaced ngrok's older module-based approach to configuring middleware like...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/10be0954ea5e4f8b5cc53cbf5ef0d2b9?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/10be0954ea5e4f8b5cc53cbf5ef0d2b9?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"ngrok Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"ngrok Blog","logo":"https://media.daily.dev/image/upload/s--718XXxvE--/f_auto,q_auto/v1787469610/logos/ngrok?_a=BAMAMicg0","url":"https://daily.dev/sources/ngrok"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"devtools,networking,api-gateway","timeRequired":"PT13M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"ngrok Blog","item":"https://daily.dev/sources/ngrok"},{"@type":"ListItem","position":3,"name":"How we built the Traffic Policy module and its actions"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/how-we-built-the-traffic-policy-module-and-its-actions-bfmcsrtax#faq","mainEntity":[{"@type":"Question","name":"What is ngrok Traffic Policy and how does it differ from ngrok's old modules system?","acceptedAnswer":{"@type":"Answer","text":"Traffic Policy is ngrok's unified system for conditionally shaping requests and responses using the Common Expression Language (CEL), replacing the older per-form-factor module system. Unlike modules, which could only be toggled on or off per endpoint with inconsistent configuration across the CLI agent, SDKs, Kubernetes Operator, and API, Traffic Policy applies conditional rules based on paths, headers, or origin across three phases: on_tcp_connect, on_http_request, and on_http_response. Developers evaluating traffic-shaping approaches can track ngrok's Traffic Policy evolution on daily.dev."}},{"@type":"Question","name":"How does ngrok scope CEL environment variables for performance in Traffic Policy?","acceptedAnswer":{"@type":"Answer","text":"Ngrok compiles each CEL expression into an AST and applies a custom decorator called accessedVarTracker that records only the variables actually referenced in that expression. At runtime, only those tracked variables are fetched before evaluation, avoiding the overhead of resolving more than 100 available connection variables for every request or response passing through the handler chain. Engineers optimizing rule-evaluation pipelines can follow deep dives like this on daily.dev."}},{"@type":"Question","name":"What actions are available in ngrok Traffic Policy for shaping HTTP, TLS, and TCP traffic?","acceptedAnswer":{"@type":"Answer","text":"Ngrok Traffic Policy actions include Add Headers, Remove Headers, Compress Response, Deny, Restrict IPs, JWT Validation, Rate Limit, URL Rewrite, Redirect, and Log, covering HTTP, TLS, and TCP protocols depending on the action. These migrated existing module functionality (like IP restriction) while adding new capabilities such as JWT validation and rate limiting that were never available as standalone modules. Teams configuring API gateway rules can keep up with new traffic-shaping actions via daily.dev."}}]}
```

