Plugin conditions allow you to attach an optional condition expression to any plugin.
When a request comes in, Kong Gateway evaluates the expression immediately before the plugin’s access phase.
If the expression evaluates to true, the plugin runs normally. If it evaluates to false, the plugin is skipped for that request.
Here are some common use cases for setting a condition on a plugin:
Skip a global plugin for specific Routes, hosts, or request paths without removing the plugin or duplicating it across individual Routes.
Enforce a plugin only for specific HTTP methods, headers, or query parameters.
Make one plugin’s execution depend on context set by a higher-priority plugin.
Condition plugin behavior on the authenticated Consumer, matched Route, or target Gateway Service.
When Kong Gateway receives a request, it matches the request to a Route and determines which plugins are in scope according to the plugin scoping rules.
For each in-scope plugin that has a condition set, Kong Gateway evaluates the expression before that plugin’s access phase runs.
The following plugin contexts always execute, regardless of the condition: init_worker, configure, certificate, and rewrite.
If the condition evaluates to false, the plugin’s access phase and later phases are skipped.
Because of this, values set during or after the response phase (for example, kong.ctx.shared values written in header_filter or body_filter) aren’t available to condition expressions.
Unlike plugin scopes, which are evaluated once at router time before any plugins run, conditions are evaluated per request, per plugin, immediately before each plugin executes.
This means a higher-priority plugin can set values in kong.ctx.shared that a lower-priority plugin’s condition can then read.
If no condition is set, the plugin always executes.
Plugin scopes are evaluated once at router time and are more efficient than conditions, which are evaluated per-request for each conditioned plugin.
Where possible, use plugin scopes to control plugin execution rather than conditions.
When conditions are necessary, keep the following in mind:
A plugin’s configuration is always loaded into memory, even if its condition evaluates to false.
Complex compound expressions with many fields are more expensive to evaluate than simple single-field expressions.
Conditions that reference kong.ctx.shared fields require a higher-priority plugin to set those values on every request, which adds its own overhead.
A condition expression is a string value assigned to the condition field of a plugin object.
It follows the same ATC (Abstract Tree Classifier) expression syntax used by Kong Gateway’s expressions router.
A predicate is the basic unit of an expression and takes the following form:
http.method == "GET"
Copied!
This predicate has the following structure:
http.method: Field
==: Operator
"GET": Constant value
Predicates are made up of smaller units that you can configure:
Object
Description
Example
Field
A value extracted from the current request or Kong Gateway context. An absent field value always causes the predicate to evaluate to false. The field always appears on the left side of the predicate.
http.method
Constant value
The value that the field is compared against. Always appears on the right side of the predicate.
"GET"
Operator
Defines the comparison to perform between the field and the constant value. Always appears between the field and the constant value.
==
Predicate
Compares a field against a constant value using the given operator. Returns true if the comparison passes, false if it does not.
Types define what you can use for a predicate’s field and constant value. Expressions language is strongly typed. Operations are only performed
if such an operation makes sense in regard to the actual type of field and constant.
Type conversion at runtime is not supported, either explicitly or implicitly. Types
are always known at the time a route is parsed. An error is returned
if the operator cannot be performed on the provided field and constant.
The expressions language currently supports the following types:
Object
Description
Field type
Constant type
String
A string value, always in valid UTF-8. They can be defined with string literal that looks like "content". You can also use the following escape sequences:
\n: Newline character
\r: Carriage return character
\t: Horizontal tab character
\\: The \ character
\": The " character
Supported
Supported
IpCidr
Range of IP addresses in CIDR format. Can be either IPv4 (net.src.ip in 192.168.1.0/24) or IPv6 (net.src.ip in fd00::/8). The expressions parser rejects any CIDR literal where the host portion contains any non-zero bits. This means that 192.168.0.1/24 won’t pass the parser check because the intention of the author is unclear.
Not supported
Supported
IpAddr
A single IP address in IPv4 Dot-decimal notation (net.src.ip == 192.168.1.1), or the standard IPv6 Address Format (net.src.ip == fd00::1). Can be either IPv4 or IPv6.
Supported
Supported
Int
A 64-bit signed integer. There is only one integer type in expressions. All integers are signed 64-bit integers. Integer literals can be written as 12345, -12345, or in hexadecimal format, such as 0xab12ff, or in octet format like 0751.
Supported
Supported
Regex
Regex are written as String literals, but they are parsed when the ~ regex operator is present and checked for validity according to the Rust regex crate syntax. For example, in the following predicate, the constant is parsed as a regex: http.path ~ r#"/foo/bar/.+"#
Not supported
Supported
In addition, the expressions router also supports one composite type, Array. Array types are written as Type[].
For example: String[], Int[]. Currently, arrays can only be present in field values. They are used in
case one field could contain multiple values. For example, http.headers.x or http.queries.x.
Plugin conditions support all standard HTTP fields from the expressions router, plus additional context fields that are only available during plugin execution.
These fields reflect the state of the incoming HTTP request at the time the condition is evaluated.
These values may have been modified by higher-priority plugins before the condition is evaluated (for example, a plugin that rewrites a header or query parameter).
Field
Type
Description
http.method
String
The HTTP method of the incoming request, for example "GET" or "POST".
http.host
String
The Host header of the incoming request.
http.path
String
The normalized request path. Does not include query parameters.
http.path.segments.<index>
String
A single path segment extracted from the normalized path, using a zero-based index. For example, for /a/b/c, http.path.segments.1 returns "b".
http.path.segments.<index>_<index>
String
A range of path segments joined by /. For example, for /a/b/c, http.path.segments.0_1 returns "a/b".
http.path.segments.len
Int
The number of segments in the normalized path. For example, /a/b/c returns 3.
http.headers.<header_name>
String[]
The value(s) of the specified request header. Header names are always normalized to lowercase with underscores, so X-My-Header becomes http.headers.x_my_header.
http.queries.<param_name>
String[]
The value(s) of the specified query parameter.
net.src.ip
IpAddr
The IP address of the client.
net.src.port
Int
The port used by the client to connect.
net.dst.ip
IpAddr
The listening IP address where Kong Gateway accepted the connection.
net.dst.port
Int
The listening port where Kong Gateway accepted the connection.
Hyphens (-) in header names must be replaced with underscores (_) in ATC expressions.
For example, x-my-header becomes http.headers.x_my_header.
The following fields are populated during plugin execution and reflect the Gateway context at the time the condition is evaluated.
Field
Type
Description
consumer.id
String
The UUID of the authenticated consumer, if one has been identified by an earlier plugin.
consumer.username
String
The username of the authenticated consumer.
consumer.custom_id
String
The custom ID of the authenticated consumer.
route.id
String
The UUID of the matched route.
route.name
String
The name of the matched route.
service.id
String
The UUID of the target service.
service.name
String
The name of the target service.
kong.ctx.shared.KEY_NAME
String
A value from the kong.ctx.shared table, set by a higher-priority plugin earlier in the same request.
Notes:
consumer.* fields are only populated after an authentication plugin (such as Key Auth or Basic Auth) has run.
Conditions referencing consumer fields must be on a plugin with a lower priority than the authentication plugin.
kong.ctx.shared.KEY_NAME fields are only populated if a higher-priority plugin has set them during the access phase.
Values set during the response phase are not available.
An operator defines the desired comparison action to be performed on the field against the provided constant value. The operator always displays in the middle of the predicate, between the field and constant value.
The expressions language supports a rich set of operators that can be performed on various data types.
Operator
Name
Description
==
Equals
Field value is equal to the constant value.
!=
Not equals
Field value does not equal the constant value.
~
Regex match
Field value matches regex.
^=
Prefix match
Field value starts with the constant value.
=^
Postfix match
Field value ends with the constant value.
>=
Greater than or equal
Field value is greater than or equal to the constant value.
>
Greater than
Field value is greater than the constant value.
<=
Less than or equal
Field value is less than or equal to the constant value.
<
Less than
Field value is less than the constant value.
in
In
Field value is inside the constant value. This operator is used with IpAddr and IpCidr types to perform an efficient IP list check.
For example, net.src.ip in 192.168.0.0/24 only returns true if the value of net.src.ip is within 192.168.0.0/24.
not in
Not in
Field value is not inside the constant value. This operator is used with IpAddr and IpCidr types to perform an efficient IP list check.
For example, net.src.ip in 192.168.0.0/24 only returns true if the value of net.src.ip is within 192.168.0.0/24.
contains
Contains
Field value contains the constant value. This operator is used to check the existence of a string inside another string.
For example, http.header contains \"foo\" returns true if foo can be found anywhere inside http.header. This will match an HTTP.header that looks like x-foo, x-abc-foo, or x-fooy, for example.
&&
And
Returns true if both expressions on the left and right sides evaluate to true.
||
Or
Returns true if any expressions on the left or right side evaluate to true.
(Expression)
Parenthesis
Groups expressions together to be evaluated first.
!
Not
Negates the result of a parenthesized expression.
The ! operator can only be used with parenthesized expression like !(foo == 1), it cannot be used with a bare predicate like ! foo == 1.”
Depending on the field type, only certain content types and operators are supported.
Field type
Supported content types and their supported operators
String
String: ==, !=, ~, ^=, =^, contains
Regex: ~
IpAddr
IpCidr: in, not in
IpAddr: ==
Int
Int: ==, !=, >=, >, <=, <
Expression
Regex: &&, ||
The ~ regex operator does not automatically anchor to the start of the string.
http.path ~ r#"/foo/\d"# would match /foo/1 and /other/foo/1.
To anchor from the start, use the ^ character: http.path ~ r#"^/foo/\d"#.
When Kong Gateway is running with debug logging enabled, a log line is emitted for each
condition evaluation, showing the plugin name, plugin ID, the expression, and the result:
Routes with expression router conditions should be used instead of per-plugin conditionals wherever practical,
since Route expressions will be more performant than plugin conditions.
This is because:
The init phase of plugins on excluded Routes won’t execute.
The plugin conditional won’t need to be evaluated.
While the conditional expression language doesn’t support this explicitly, you could use a plugin such as Datakit or Pre-Function to parse the body, extract the value required, and put the value in a variable in the request context.
The conditional expression for the plugin can then be set based on that variable.