This is an automated email from the ASF dual-hosted git repository.

Yilialinn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-website.git


The following commit(s) were added to refs/heads/master by this push:
     new dbd07aaac10 docs(seo): add a practical security policy example (#2134)
dbd07aaac10 is described below

commit dbd07aaac10cb6e3bab8e9e00981c120201e04d4
Author: Yilia Lin <[email protected]>
AuthorDate: Sat Oct 10 15:11:46 2026 +0800

    docs(seo): add a practical security policy example (#2134)
---
 .github/workflows/deploy.yml                    |  7 -------
 website/learning-center/api-gateway-security.md | 28 +++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 935aa21ce50..b7e4c66689a 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -183,16 +183,9 @@ jobs:
           
website/build/docs/apisix/next/plugins/cors/index.html|https://docs.api7.ai/hub/cors
           
website/build/zh/docs/apisix/next/plugins/cors/index.html|https://docs.apiseven.com/hub/cors
           EOF
-          # `mcp-bridge` shipped in 3.18, so the version-less page this fixture
-          # used to find missing now exists and the `next` page points at it.
           # The self-canonical half of the contract is unfixtured while every
           # `next` doc also ships in the latest release; give it a fixture 
again
           # as soon as a doc lands on `next` alone.
-          f=website/build/docs/apisix/next/plugins/mcp-bridge/index.html
-          test -f "$f"
-          test "$(grep -o 'rel="canonical"' "$f" | wc -l)" -eq 1
-          grep -q 'name="robots" content="noindex,follow"' "$f"
-          grep -q 'rel="canonical" 
href="https://apisix.apache.org/docs/apisix/plugins/mcp-bridge/";' "$f"
 
       - name: Update sitemap.xml
         run: |
diff --git a/website/learning-center/api-gateway-security.md 
b/website/learning-center/api-gateway-security.md
index 6d19a87e6da..5b4b2454336 100644
--- a/website/learning-center/api-gateway-security.md
+++ b/website/learning-center/api-gateway-security.md
@@ -116,6 +116,34 @@ For **mutual TLS**, APISIX supports [mTLS 
configuration](/docs/apisix/mtls/) for
 
 APISIX also supports JWT authentication, key authentication, OpenID Connect, 
rate limiting with multiple algorithms, and request body validation. Its plugin 
architecture lets teams compose gateway policies per route while retaining 
application-level authorization and validation in the services that own the 
data.
 
+### Example: Authenticate and Rate-Limit a Route
+
+For a protected API, first create a Consumer with a `key-auth` Credential. 
Then enable [key-auth](/docs/apisix/plugins/key-auth/) and 
[limit-count](/docs/apisix/plugins/limit-count/) on the Route. The JSON below 
is the value of the Route's `plugins` field, not a complete Route object; use 
it in a valid Route with a URI and an Upstream, whether configured directly or 
through a Service. Adjust the quota to the backend's capacity and the client 
contract:
+
+```json
+{
+  "key-auth": {
+    "hide_credentials": true
+  },
+  "limit-count": {
+    "count": 100,
+    "time_window": 60,
+    "rejected_code": 429,
+    "key_type": "var_combination",
+    "key": "$remote_addr $consumer_name",
+    "policy": "local"
+  }
+}
+```
+
+Keep these boundaries in mind when applying the example:
+
+- **Quota key:** On this Route, `key-auth` authenticates in the rewrite phase 
before `limit-count` runs in the access phase. The counter key combines the 
observed address and the authenticated Consumer name, so the quota applies to 
each pair. If you change the authentication flow, verify that `$consumer_name` 
is populated before using it in a limit key; an empty value can change the 
quota's scope.
+- **Client address:** Behind a proxy, `$remote_addr` may be the proxy's 
address. Configure a [trusted real-IP source](/docs/apisix/plugins/real-ip/) if 
the quota must use the original client address.
+- **Counter storage:** With `policy: local`, each APISIX instance keeps its 
own counters. Use an appropriate shared Redis policy when a quota must apply 
across instances.
+- **Credential forwarding:** `hide_credentials` removes the header or query 
parameter used to authenticate the request. It does not guarantee removal of a 
duplicate key supplied in the other carrier; enforce a single accepted carrier 
or strip alternate copies before forwarding if strict non-forwarding is 
required.
+- **Authorization:** This gateway policy does not decide whether a Consumer 
may access a particular order or account. The application must still check 
resource ownership.
+
 ## FAQ
 
 ### What is the difference between API gateway security and API security?

Reply via email to