Expressions
Traffic Policy module enables you to filter inbound and outbound traffic with Common Expression Language (CEL) expressions. Each policy rule expression must evaluate to true in order for the rule's actions to take effect against traffic. In addition to CEL's built-in functions and macros we provide additional variables for the connection, request and response along with custom macros.
Connection Variables
The following connection variables are available on the conn
struct:
Name | Type | Description |
---|---|---|
conn.ClientIP | string | The source IP of the HTTP connection to the ngrok endpoint. |
conn.Geo.CountryCode | string | The two-letter ISO country code based on the client IP. |
conn.Geo.Latitude | string | The approximate latitude based on the client IP. |
conn.Geo.LatLongRadiusKm | string | The radius in kilometers around the latitude and longitude where the client IP is likely to originate. |
conn.Geo.Longitude | string | The approximate longitude based on the client IP. |
conn.ClientIP
The source IP of the HTTP connection to the ngrok endpoint as a string.
- YAML
- JSON
# snippet
---
expressions:
- "conn.ClientIP in ['::1', '127.0.0.1']"
// snippet
{
"expressions": [
"conn.ClientIP in ['::1', '127.0.0.1']"
]
}
conn.Geo.CountryCode
The two-letter ISO country code based on the client IP.
- YAML
- JSON
# snippet
---
expressions:
- "conn.Geo.CountryCode != 'US'"
// snippet
{
"expressions": [
"conn.Geo.CountryCode != 'US'"
]
}
conn.Geo.Latitude
The approximate latitude based on the client IP.
- YAML
- JSON
# snippet
---
expressions:
- "double(conn.Geo.Latitude) >= 45.0"
// snippet
{
"expressions": [
"double(conn.Geo.Latitude) >= 45.0"
]
}
conn.Geo.LatLongRadiusKm
The radius in kilometers around the latitude and longitude where the client IP is likely to originate.
- YAML
- JSON
# snippet
---
expressions:
- "conn.Geo.LatLongRadiusKm <= '20'"
// snippet
{
"expressions": [
"conn.Geo.LatLongRadiusKm <= '20'"
]
}
conn.Geo.Longitude
The approximate longitude based on the client IP.
- YAML
- JSON
# snippet
---
expressions:
- "double(conn.Geo.Longitude) <= -93.0"
// snippet
{
"expressions": [
"double(conn.Geo.Longitude) <= -93.0"
]
}
Request Variables
The following request variables are available on the req
struct:
Name | Type | Description |
---|---|---|
req.ClientTLS.CertCN | string | The subject common name of the client's leaf TLS certificate. |
req.ClientTLS.CipherSuite | string | The cipher suite negotiated on the connection. |
req.ClientTLS.SNI | string | The Server Name Indication extension sent by the client. |
req.ClientTLS.Version | string | The TLS Version used on the connection. |
req.ContentLength | int | The length of the content associated with the request. |
req.Cookies | list | The list of HTTP cookie objects provided in the request. |
req.Method | string | The request method. |
req.URL | string | The URL of the request. |
req.Params | map | The query parameters of the request URL wherein a string key maps to a list of string values. |
req.Protocol | string | The protocol version of the request. |
req.Host | string | The host of the request. |
req.Location | string | The 'Location' header of the request. |
req.Headers | map | The headers of the request wherein a string key maps to a list of string values. Header keys must be written in canonical format. |
req.Trailers | map | The trailers of the request wherein a string key maps to a list of string values. Trailer keys must be written in canonical format. |
req.ClientTLS.CertCN
The subject common name of the client's leaf TLS certificate.
- YAML
- JSON
# snippet
---
expressions:
- "req.ClientTLS.CertCN.startsWith('example')"
// snippet
{
"expressions": [
"req.ClientTLS.CertCN.startsWith('example')"
]
}
req.ClientTLS.CipherSuite
The cipher suite negotiated on the connection.
- YAML
- JSON
# snippet
---
expressions:
- "req.ClientTLS.CipherSuite.contains('SHA256')"
// snippet
{
"expressions": [
"req.ClientTLS.CipherSuite.contains('SHA256')"
]
}
req.ClientTLS.SNI
The Server Name Indication extension sent by the client.
- YAML
- JSON
# snippet
---
expressions:
- "req.ClientTLS.SNI.startsWith('domain')"
// snippet
{
"expressions": [
"req.ClientTLS.SNI.startsWith('domain')"
]
}
req.ClientTLS.Version
The TLS Version used on the connection.
- YAML
- JSON
# snippet
---
expressions:
- "req.ClientTLS.Version.contains('1.3')"
// snippet
{
"expressions": [
"req.ClientTLS.Version.contains('1.3')"
]
}
req.ContentLength
The length of the content associated with the request.
- YAML
- JSON
# snippet
---
expressions:
- "req.ContentLength > 10000000"
// snippet
{
"expressions": [
"req.ContentLength > 10000000"
]
}
req.Method
The request method.
- YAML
- JSON
# snippet
---
expressions:
- "req.Method == 'POST' || req.Method == 'PUT'"
// snippet
{
"expressions": [
"req.Method == 'POST' || req.Method == 'PUT'"
]
}
req.Cookies
The list of HTTP cookie objects provided in the request.
- YAML
- JSON
# snippet
---
expressions:
- "size(req.Cookies) > 0"
// snippet
{
"expressions": [
"size(req.Cookies) > 0"
]
}
req.URL
The URL of the request.
- YAML
- JSON
# snippet
---
expressions:
- "req.URL.contains('/admin')"
// snippet
{
"expressions": [
"req.URL.contains('/admin')"
]
}
req.Params
The query parameters of the request URL wherein a string key maps to a list of string values.
- YAML
- JSON
# snippet
---
expressions:
- "'bar' in req.Params['foo']"
// snippet
{
"expressions": [
"'bar' in req.Params['foo']"
]
}
req.Protocol
The protocol version of the request.
- YAML
- JSON
# snippet
---
expressions:
- "`req.Protocol == 'HTTP/1.1'"
// snippet
{
"expressions": [
"`req.Protocol == 'HTTP/1.1'"
]
}
req.Host
The host of the request.
- YAML
- JSON
# snippet
---
expressions:
- "req.Host.contains(':8080')"
// snippet
{
"expressions": [
"req.Host.contains(':8080')"
]
}
req.Location
The 'Location' header of the request.
- YAML
- JSON
# snippet
---
expressions:
- "req.Location == '/index.html'"
// snippet
{
"expressions": [
"req.Location == '/index.html'"
]
}
req.Headers
The headers of the request wherein a string key maps to a list of string values.
- YAML
- JSON
# snippet
---
expressions:
- "'Fizz' in req.Headers['Baz']"
// snippet
{
"expressions": [
"'Fizz' in req.Headers['Baz']"
]
}
req.Trailers
The trailers of the request wherein a string key maps to a list of string values.
- YAML
- JSON
# snippet
---
expressions:
- "'Fizz' in req.Trailers['Baz']"
// snippet
{
"expressions": [
"'Fizz' in req.Trailers['Baz']"
]
}
Response Variables
The following response variables are available on the res
struct:
Name | Type | Description |
---|---|---|
res.ContentLength | int | The length of the content associated with the response. |
res.Cookies | list | The list of HTTP cookie objects provided in the response. |
res.Headers | map | The headers of the response wherein a string key maps to a list of string values. Header keys must be written in canonical format. |
res.Location | string | The 'Location' header of the response. |
res.ServerTLS.CertCN | string | The subject common name of the leaf TLS certificate. |
res.ServerTLS.CipherSuite | string | The cipher suite negotiated on the connection. |
res.ServerTLS.SNI | string | The Server Name Indication extension sent by the client. |
res.ServerTLS.Version | string | The TLS Version used on the connection. |
res.StatusCode | string | The status code of the response. |
res.Trailers | map | The trailers of the response wherein a string key maps to a list of string values. Trailer keys must be written in canonical format. |
res.ContentLength
The length of the content associated with the response.
- YAML
- JSON
# snippet
---
expressions:
- "res.ContentLength != 0"
// snippet
{
"expressions": [
"res.ContentLength != 0"
]
}
res.Cookies
The list of HTTP cookie objects provided in the response.
- YAML
- JSON
# snippet
---
expressions:
- "size(req.Cookies) > 0"
// snippet
{
"expressions": [
"size(req.Cookies) > 0"
]
}
res.Headers
The headers of the response wherein a string key maps to a list of string values.
- YAML
- JSON
# snippet
---
expressions:
- "'Fizz' in res.Headers['Baz']"
// snippet
{
"expressions": [
"'Fizz' in res.Headers['Baz']"
]
}
res.Location
The 'Location' header of the response.
- YAML
- JSON
# snippet
---
expressions:
- "res.Location == '/index.html'"
// snippet
{
"expressions": [
"res.Location == '/index.html'"
]
}
res.ServerTLS.CertCN
The subject common name of the leaf TLS certificate.
- YAML
- JSON
# snippet
---
expressions:
- "res.ClientTLS.CertCN.startsWith('example')"
// snippet
{
"expressions": [
"res.ClientTLS.CertCN.startsWith('example')"
]
}
res.ServerTLS.CipherSuite
The cipher suite negotiated on the connection.
- YAML
- JSON
# snippet
---
expressions:
- "res.ClientTLS.CipherSuite.contains('SHA256')"
// snippet
{
"expressions": [
"res.ClientTLS.CipherSuite.contains('SHA256')"
]
}
res.ServerTLS.SNI
The Server Name Indication extension sent by the client.
- YAML
- JSON
# snippet
---
expressions:
- "res.ClientTLS.SNI.startsWith('domain')"
// snippet
{
"expressions": [
"res.ClientTLS.SNI.startsWith('domain')"
]
}
res.ServerTLS.Version
The TLS Version used on the connection.
- YAML
- JSON
# snippet
---
expressions:
- "res.ClientTLS.Version.contains('1.3')"
// snippet
{
"expressions": [
"res.ClientTLS.Version.contains('1.3')"
]
}
res.StatusCode
The status code of the response.
- YAML
- JSON
# snippet
---
expressions:
- "res.StatusCode >= '300'"
// snippet
{
"expressions": [
"res.StatusCode >= '300'"
]
}
res.Trailers
The trailers of the response wherein a string key maps to a list of string values.
- YAML
- JSON
# snippet
---
expressions:
- "'fizz' in res.Trailers['baz']"
// snippet
{
"expressions": [
"'fizz' in res.Trailers['baz']"
]
}
Macros
CEL provides a set of predefined macros that can also be used in policy expressions. For convenience, the following custom macros are also supported:
Name | Return Type | Description |
---|---|---|
hasReqHeader(string) | bool | Returns true or false if the provided header key is present on the request. Header keys must be written in canonical format. |
getReqHeader(string) | list | Returns a list of header values for the provided key on the request. Header keys must be written in canonical format. |
hasQueryParam(string) | bool | Returns true or false if the specified query parameter key is part of the request URL. |
getQueryParam(string) | list | Returns a list of the query parameter values from the request URL for the specified key. |
hasReqCookie(string) | bool | Returns true or false if a cookie exists on the request with the specified name. |
getReqCookie(string) | bool | Returns the cookie struct for the specified cookie name, if it exists on the request. |
hasResHeader(string) | bool | Returns true or false if the provided header key is present on the response. Header keys must be written in canonical format. |
getResHeader(string) | list | Returns a list of header values for the provided key on the response. Header keys must be written in canonical format. |
hasResCookie(string) | bool | Returns true or false if a cookie exists on the response with the specified name. |
getResCookie(string) | bool | Returns the cookie struct for the specified cookie name, if it exists on the response. |
inCidrRange(ip string, cidr string) | bool | Returns true or false if the provided IP address falls within the provided CIDR range. Returns false if the provided CIDR range is invalid. |
inCidrRanges(ip string, cidrs list) | bool | Returns true or false if the provided IP address falls within any of the provided CIDR ranges. Ignores any provided CIDR ranges that are invalid. |
hasReqHeader(string)
Returns true
or false
if the provided header key is present on the request. Header keys must be written in canonical format.
- YAML
- JSON
# snippet
---
expressions:
- "hasReqHeader('X-Version-Id')"
// snippet
{
"expressions": [
"hasReqHeader('X-Version-Id')"
]
}
getReqHeader(string)
Returns a list of header values for the provided key on the request. Header keys must be written in canonical format.
- YAML
- JSON
# snippet
---
expressions:
- "getReqHeader('User-Agent').exists(v, v.matches('(?i)google-images'))"
// snippet
{
"expressions": [
"getReqHeader('User-Agent').exists(v, v.matches('(?i)google-images'))"
]
}
hasQueryParam(string)
Returns true or false if the specified query parameter key is part of the request URL.
- YAML
- JSON
# snippet
---
expressions:
- "hasQueryParam('q')"
// snippet
{
"expressions": [
"hasQueryParam('q')"
]
}
getQueryParam(string)
Returns a list of the query parameter values from the request URL for the specified key.
- YAML
- JSON
# snippet
---
expressions:
- "'asc' in getQueryParam('sort')"
// snippet
{
"expressions": [
"'asc' in getQueryParam('sort')"
]
}
hasReqCookie(string)
Returns true or false if a cookie exists on the request with the specified name.
- YAML
- JSON
# snippet
---
expressions:
- "hasReqCookie('session')"
// snippet
{
"expressions": [
"hasReqCookie('session')"
]
}
getReqCookie(string)
Returns the cookie struct for the specified cookie name, if it exists on the request.
- YAML
- JSON
# snippet
---
expressions:
- "getReqCookie('session').Secure"
// snippet
{
"expressions": [
"getReqCookie('session').Secure"
]
}
hasResHeader(string)
Returns true or false if the provided header key is present on the response. Header keys must be written in canonical format.
- YAML
- JSON
# snippet
---
expressions:
- "hasResHeader('Content-Type')"
// snippet
{
"expressions": [
"hasResHeader('Content-Type')"
]
}
getResHeader(string)
Returns a list of header values for the provided key on the response. Header keys must be written in canonical format.
- YAML
- JSON
# snippet
---
expressions:
- "'application/json' in getResHeader('Content-Type')"
// snippet
{
"expressions": [
"'application/json' in getResHeader('Content-Type')"
]
}
hasResCookie(string)
Returns true or false if a cookie exists on the response with the specified name.
- YAML
- JSON
# snippet
---
expressions:
- "hasResCookie('_device_id')"
// snippet
{
"expressions": [
"hasResCookie('_device_id')"
]
}
getResCookie(string)
Returns the cookie struct for the specified cookie name, if it exists on the response.
- YAML
- JSON
# snippet
---
expressions:
- "getResCookie('_device_id').Value == 'mobile-phone-14'"
// snippet
{
"expressions": [
"getResCookie('_device_id').Value == 'mobile-phone-14'"
]
}
inCidrRange(ip string, cidr string)
Returns true or false if the provided IP address falls within the provided CIDR range. Returns false if the provided CIDR range is invalid.
- YAML
- JSON
# snippet
---
expressions:
- "inCidrRange(conn.ClientIP, '66.249.66.1/24')"
// snippet
{
"expressions": [
"inCidrRange(conn.ClientIP, '66.249.66.1/24')"
]
}
inCidrRanges(ip string, cidrs list)
Returns true or false if the provided IP address falls within any of the provided CIDR ranges. Ignores any provided CIDR ranges that are invalid.
- YAML
- JSON
# snippet
---
expressions:
- "inCidrRanges(conn.ClientIP, ['66.249.66.1/24', '2001:4860::/32'])"
// snippet
{
"expressions": [
"inCidrRanges(conn.ClientIP, ['66.249.66.1/24', '2001:4860::/32'])"
]
}