Skip to main content

Version: latest

Conditionally Disable Global Plugins

Global plugins apply to all routes by default, which is useful for enforcing organization-wide policies such as logging, rewriting, or traffic controls. However, some routes may need to be exempt from certain global plugins.

This guide walks you through how to conditionally disable global plugins for specific routes using route labels and the _meta.filter mechanism.

How It Works

The approach uses three components:

  1. Route labels: A label (e.g., api7_disable_global_rules: response-rewrite) on routes that should skip certain global plugins.
  2. serverless-pre-function: A global serverless function that reads the route label and registers it as a custom NGINX variable.
  3. _meta.filter: A condition on the global plugin that evaluates the variable and skips execution when it matches.

Prerequisites

  • An API7 Enterprise instance is running.
  • A Gateway Group is created and a Gateway instance is running.
  • A token from the Dashboard.

This approach returns the raw route label string and uses a regex filter on the global plugin. It was validated end to end in the local API7 Gateway environment with a global response-rewrite rule.

Step 1: Create the Serverless Function

Configure the serverless-pre-function as a global plugin that registers a custom variable from the route label:

curl -k "https://localhost:7443/apisix/admin/global_rules/serverless-pre-function?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions": [
"return function(conf, ctx) local core = require \"apisix.core\" core.ctx.register_var(\"api7_disable_global_rules\", function(ctx) local route = ctx.matched_route and ctx.matched_route.value if route and route.labels then return route.labels.api7_disable_global_rules end return 1 end) end"
]
}
}
}'

Step 2: Configure the Global Plugin with _meta.filter

Add _meta.filter to the global plugin you want to conditionally skip. The following example applies a response header globally unless the route label contains response-rewrite:

curl -k "https://localhost:7443/apisix/admin/global_rules/response-rewrite?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"plugins": {
"response-rewrite": {
"headers": {
"set": {
"X-Global-Rule": "applied"
}
},
"_meta": {
"filter": [
["api7_disable_global_rules", "!", "~~", ".*response-rewrite.*"]
]
}
}
}
}'

Step 3: Label Routes to Skip the Plugin

Add the api7_disable_global_rules label to routes that should bypass the global plugin.

# 1. Create a Service for the routes
curl -k "https://localhost:7443/apisix/admin/services/global-exemption-service?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "global-exemption-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{
"host": "httpbin.org",
"port": 80,
"weight": 100
}
]
}
}'

# 2. Create a labeled route that skips the global plugin
curl -k "https://localhost:7443/apisix/admin/routes/global-exempt-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "global-exempt-route",
"paths": ["/anything/global-exempt"],
"methods": ["GET"],
"labels": {
"api7_disable_global_rules": "response-rewrite"
},
"service_id": "global-exemption-service"
}'

# 3. Create a normal route where the global plugin still applies
curl -k "https://localhost:7443/apisix/admin/routes/global-protected-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "global-protected-route",
"paths": ["/anything/global-protected"],
"methods": ["GET"],
"service_id": "global-exemption-service"
}'

Verify

Send a request to the labeled route:

curl -i "http://127.0.0.1:9080/anything/global-exempt"

The response should not include the X-Global-Rule header because response-rewrite is skipped.

Send a request to the non-labeled route:

curl -i "http://127.0.0.1:9080/anything/global-protected"

The response should include X-Global-Rule: applied because the global plugin is active.

Option 2: List-Based Match

This approach returns a list of plugin names from the label and uses the has operator in _meta.filter.

caution

Complex regex expressions may incur more processing overhead compared to the list-based approach.

Serverless Function

Use this variant when you prefer exact list membership checks for comma-separated labels:

adc.yaml
global_rules:
serverless-pre-function:
phase: rewrite
functions:
- >-
return function(conf, ctx)
local core = require "apisix.core"
core.ctx.register_var("api7_disable_global_rules", function(ctx)
local route = ctx.matched_route and ctx.matched_route.value
if route and route.labels then
local value = route.labels.api7_disable_global_rules
if value then
local disable_plugins = {}
for plugin_name in string.gmatch(value, "[^,]+") do
local trimmed_name = string.gsub(plugin_name, "^%s*(.-)%s*$", "%1")
if trimmed_name and trimmed_name ~= "" then
table.insert(disable_plugins, trimmed_name)
end
end
return disable_plugins
end
end
return 1
end)
end

Global Plugin with has Filter

Use the has operator to check whether the returned list contains the plugin name:

adc.yaml
global_rules:
response-rewrite:
_meta:
filter:
- - api7_disable_global_rules
- "!"
- has
- response-rewrite
headers:
set:
X-Global-Rule: applied

Understanding _meta.filter

The _meta field is available on every plugin and supports the following options:

FieldTypeDescription
disablebooleanDisable the plugin entirely
error_responsestring/objectCustom error response when the plugin rejects a request
priorityintegerOverride the plugin's execution priority
filterarrayRuntime expression; the plugin is skipped if the expression evaluates to false

The filter field uses the same expression syntax as route matching (radixtree vars). Supported operators include ==, !=, ~~ (regex), has (list contains), and more.

Additional Resources

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation