Convert an ngrok Traffic Policy
Turn an ngrok Traffic Policy file (YAML or JSON) into the equivalent ngris policy YAML, with a report of what was converted, what was approximated and what was skipped. Nothing is created or changed on your account: save ngris_yaml as a file and pass it to the agent with ngris http 3000 --traffic-policy policy.yaml (see Traffic rules), or add the rules to an endpoint with Add Rule.
How it converts:
- An ngrok rule holds several
actions; an ngris rule is one action. Each action becomes its own ngris rule carrying the ngrok rule'snameand itsexpressionsjoined with&&. Phases and order are kept.on_tcp_connectrules go toon_udp_connectwhentunnel_typeisudp. - In expressions only
req.url.pathis renamed (toreq.path); everything else is copied as written — check the result with Test a Rule Expression. - Converted directly:
add-headers,remove-headers,restrict-ips(withallow/denylists),url-rewrite,redirect,custom-response,compress-response. - Converted with a warning to review:
rate-limit(ngrok's token bucket becomes a fixed window),deny(becomes acustom-response, 403 by default),request-body-find-replace/response-body-find-replace(one literalreplace-bodyrule per replacement),owasp-crs-request/owasp-crs-response(thewafrule in detect mode), andjwt-validation,verify-webhook,set-vars,circuit-breaker(config copied as is; the fields differ). - Skipped with a warning:
oauth,oidcandbasic-auth(sign-in is an endpoint setting on ngris — see Update Endpoint Auth),restrict-ipsthat only references ngrok IP policies,forward-internal,http-request,close-connection,log,terminate-tls,sse-find-replace, any unknown action, and every action underon_event_stream_message.
Any signed-in member can call it; only a suspended account is refused.
Request body
policy string Req
The ngrok Traffic Policy document, YAML or JSON, as a string. The whole request body may be up to 256 KiB.
tunnel_type string
http (default), tcp or udp. Only udp changes the result (connect-phase rules go to on_udp_connect).Response (200 OK)
ngris_yaml string
The ngris policy: rules grouped under
on_tcp_connect, on_udp_connect, on_http_request and on_http_response, each with type and, when set, name, expression and config. {} when nothing could be converted.converted integer
ngris rules produced.
skipped integer
ngrok actions with no ngris equivalent.
warnings array of string | null
One line per approximated or skipped action, saying what to check or redo by hand.
null when there are none.Errors
400 Bad Request
invalid request body (not JSON, or over 256 KiB), empty policy, or could not parse ngrok policy: … (the document isn't valid YAML / JSON).401 Unauthorized
Missing or invalid auth.
403 Forbidden
The account is suspended (
account_suspended).415 Unsupported Media Type
The request has no
Content-Type: application/json header.policy.yml (ngrok)
on_http_request:
- expressions:
- "req.url.path.startsWith('/admin')"
actions:
- type: restrict-ips
config:
allow:
- 203.0.113.0/24
- actions:
- type: rate-limit
config:
capacity: 100
rate: 60s
bucket_key:
- conn.client_ip
- type: log
Request
jq -n --rawfile policy policy.yml '{policy: $policy, tunnel_type: "http"}' | \
curl -X POST "https://api.ngris.com/v1/tools/convert-ngrok-policy" \
-H "X-API-KEY: <your_api_key>" \
-H "Content-Type: application/json" \
--data-binary @-
Response — 200 OK
{
"converted": 2,
"ngris_yaml": "on_http_request:\n - type: restrict-ips\n expression: req.path.startsWith('/admin')\n config:\n allow:\n - 203.0.113.0/24\n - type: rate-limit\n config:\n key_name: \"\"\n limit: 100\n scope: ip\n window: 60\n",
"skipped": 1,
"warnings": [
"rate-limit: ngrok token-bucket (capacity/rate/bucket_key) mapped to ngris fixed-window (limit/window/scope) — close but not identical; verify limit=100 window=60s",
"log: no ngris traffic-policy equivalent — skipped"
]
}