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

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


The following commit(s) were added to refs/heads/master by this push:
     new 30ab165ab docs: add project security threat-model document + 
discoverability scaffold (#13457)
30ab165ab is described below

commit 30ab165abfba43b0e0b2aabe40c5f71788884aa0
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sun May 31 14:26:11 2026 +0200

    docs: add project security threat-model document + discoverability scaffold 
(#13457)
    
    * Add project security threat-model document + discoverability scaffold
    
    Adds three files improving the project's security-model
    discoverability for automated security scanners and triagers:
    
    - docs/en/latest/security-threat-model.md — the project's
      threat model, articulating trust boundaries, in-scope vs
      out-of-scope finding categories, and triage dispositions.
      The §4.14 open-questions section is currently RESOLVED —
      all 28 prior open questions answered by the PMC chair
      (Ming Wen) in the 2026-05-15 thread.
    - AGENTS.md — entrypoint for automated agents (scanners,
      AI assistants) pointing them at the threat model.
    - SECURITY.md — disclosure policy + threat-model pointer.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
    
    * Fix lint failures flagged on draft-threat-model PR
    
    Markdown / typos / table-shape fixes per the CI lint output.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
    
    * Index security-threat-model.md in docs/en/latest/config.json
    
    The 🍇 Markdown check requires every doc to be indexed in the
    sidebar config. Added a top-level doc entry next to ssl-protocol.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
 AGENTS.md                               |  38 ++
 SECURITY.md                             |  34 ++
 docs/en/latest/config.json              |   4 +
 docs/en/latest/security-threat-model.md | 884 ++++++++++++++++++++++++++++++++
 4 files changed, 960 insertions(+)

diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 000000000..831138725
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,38 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Apache APISIX — Agent Instructions
+
+This file is read by automated agents (security scanners, code
+analyzers, AI assistants) operating on this repository. It
+points them at the human-authored references they should
+consult before producing output.
+
+## Security Model
+
+The authoritative security threat model for Apache APISIX is
+at 
[`docs/en/latest/security-threat-model.md`](docs/en/latest/security-threat-model.md).
+
+Agents producing security-relevant analysis against this
+repository should consult that document first — in particular
+the §4.3 (out of scope), §4.9 (properties NOT provided),
+§4.11a (known non-findings), and §4.13 (triage dispositions)
+sections, which govern whether a given finding is in-scope
+for Apache APISIX itself or out-of-scope (operator
+misconfiguration, downstream concern, etc.).
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..86a2145e0
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,34 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Security Policy
+
+Apache APISIX follows the Apache Software Foundation's
+vulnerability-disclosure policy. Please report security
+vulnerabilities to the ASF Security team at
+<[email protected]> per <https://www.apache.org/security/>.
+
+## Threat Model
+
+The project's threat model is at
+[`docs/en/latest/security-threat-model.md`](docs/en/latest/security-threat-model.md).
+Maintainers and automated security tooling consult that
+document to determine what counts as a security
+vulnerability in Apache APISIX, what is out of scope, and
+what triage dispositions apply.
diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json
index ec3635413..820a172d1 100644
--- a/docs/en/latest/config.json
+++ b/docs/en/latest/config.json
@@ -423,6 +423,10 @@
           "type": "doc",
           "id": "ssl-protocol"
         },
+        {
+          "type": "doc",
+          "id": "security-threat-model"
+        },
         {
           "type": "doc",
           "id": "http3"
diff --git a/docs/en/latest/security-threat-model.md 
b/docs/en/latest/security-threat-model.md
new file mode 100644
index 000000000..d22cf3f54
--- /dev/null
+++ b/docs/en/latest/security-threat-model.md
@@ -0,0 +1,884 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# Apache APISIX — Threat Model
+
+> **This is a maintainer-stewarded threat model owned by the
+> Apache APISIX PMC.** It follows the rubric at
+> <https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573>.
+> A historical first draft is preserved as a gist at
+> <https://gist.github.com/potiuk/43aa334087cf1fdb2908662e592a192a>
+> for reference; this in-repo document is the canonical version.
+> Last revised 2026-05-30.
+
+**Provenance legend** — every claim is tagged:
+
+- *(documented)* — verbatim or paraphrased from a project public
+  artefact (cited inline).
+- *(maintainer)* — confirmed by an APISIX PMC member.
+- *(inferred)* — synthesis from public artefacts; the PMC has
+  not yet confirmed. Every *(inferred)* claim also appears in
+  §4.14 as an Open Question. (None remain in the current
+  revision.)
+
+**Confidence**: ~70 *(documented)* / 28 *(maintainer)* / 0
+*(inferred)*. All §4.14 open questions have been resolved with
+the PMC; q-21 (dashboard admin-key storage) was resolved by
+reducing scan scope (see §4.11a, §4.14 q-21).
+
+---
+
+## §4.1 Header
+
+- **Project**: Apache APISIX (gateway), apisix-ingress-controller.
+  (apache/apisix-dashboard is out of current scan scope per PMC
+  decision 2026-05-26; see §4.11a.)
+- **Model version**: 2026-05-30 (revised), against `apache/apisix@main`
+  and `apache/apisix-ingress-controller@main` at the date above.
+- **Scope**: apache/apisix + apache/apisix-ingress-controller
+  (apache/apisix-dashboard out of current scan scope per PMC
+  2026-05-26).
+- **Stewardship**: this document is maintainer-stewarded by the
+  Apache APISIX PMC.
+- **Historical reference**: a first-draft version of this
+  document is preserved at
+  <https://gist.github.com/potiuk/43aa334087cf1fdb2908662e592a192a>
+  for traceability of the §4.14 promotion pass.
+- **Version binding**: this model describes APISIX as of the
+  commits listed above. A report against an earlier release (e.g.,
+  3.x) is triaged against the model as it stood for that release;
+  if a security property was added later, the earlier release is
+  not in scope. *(maintainer — confirmed by Ming Wen 2026-05-15)*
+- **Reporting cross-reference**: findings that fall under §4.8 (claimed
+  properties) should be reported privately per the project's
+  disclosure policy ([email protected]). Findings that fall under
+  §4.3 or §4.9 will be closed with a pointer to this document.
+- **Status**: **maintainer-confirmed; revised 2026-05-30.**
+
+**One-paragraph description.** Apache APISIX is a dynamic,
+cloud-native API gateway built on OpenResty (nginx + LuaJIT).
+A single APISIX deployment terminates HTTP/HTTPS/gRPC/TCP/UDP
+client traffic, applies route-matched plugin logic (auth, rate
+limiting, transformation, observability), and forwards to upstream
+services. Configuration is held in etcd (or in YAML in
+standalone mode) and mutated through the **Admin API**. The
+**apisix-ingress-controller** translates Kubernetes Ingress /
+Gateway-API resources into Admin API calls. (The
+**apisix-dashboard** — a React SPA that does the same on behalf
+of a human operator — is part of the broader APISIX project but
+is out of the current scan scope; see §4.11a.)
+
+---
+
+## §4.2 Scope and intended use
+
+**Intended deployments** *(documented — README, deployment-modes.md)*:
+
+- **Edge gateway** — single APISIX cluster in front of upstream
+  services, performing routing, auth, rate limiting, transformation.
+- **Service mesh sidecar / ingress controller** — APISIX as a
+  Kubernetes Ingress / Gateway-API implementation via
+  apisix-ingress-controller.
+- **Decoupled control-plane / data-plane deployments** — separate
+  APISIX instances configured for `role: data_plane` and
+  `role: control_plane`.
+- **Standalone mode** — file-backed config (no etcd), suited to
+  immutable infrastructure / GitOps. *(documented —
+  deployment-modes.md)*
+
+**Caller roles.** A gateway has more than one "caller":
+
+| Role | Trust level | Typical channel |
+|---|---|---|
+| **External client** | untrusted | HTTPS / HTTP / TCP / UDP traffic to 
data-plane port (default 9080). |
+| **Operator / admin** | trusted | Admin API (default 9180) or Kubernetes CRDs 
via the ingress controller. |
+| **Upstream service** | operator-trusted | HTTP / HTTPS / gRPC to backend; 
operator chose to put it behind APISIX. |
+| **etcd peer** | operator-trusted | gRPC to etcd (TLS optional). |
+| **Plugin runner subprocess** *(external plugins)* | operator-trusted | 
Unix-socket RPC; subprocess inherits APISIX user. *(documented — 
external-plugin.md)* |
+| **Operator-supplied Lua / serverless code** | operator-trusted | embedded in 
route config; executes inside the worker. *(documented — plugin-develop.md, 
serverless-pre-function plugin)* |
+
+**Component-family table.**
+
+| Family | Representative entry point | Process-external side effects | In/out 
of model |
+|---|---|---|---|
+| Gateway data-plane (Lua, OpenResty) | `POST /any-route` on `node_listen` | 
network egress to upstream, log sinks, etcd reads | **in** |
+| Gateway control-plane (Admin API) | `PUT /apisix/admin/routes/<id>` on 
`admin_listen` | etcd writes, plugin reloads | **in** |
+| etcd watch + reload | `apisix/core/config_etcd.lua` | etcd reads, in-process 
state mutation | **in** |
+| Plugin host (Lua) | each route's `plugins:` config | filesystem / network 
access available to any plugin | **in** |
+| External plugin runner | unix socket RPC | subprocess, runs as APISIX uid | 
**in** *(documented — external-plugin.md)* |
+| Stream proxy (raw TCP/UDP) | `stream_proxy` listener | upstream TCP / UDP | 
**in** |
+| Ingress controller | Kubernetes CRD watcher → Admin API | K8s API, etcd 
writes via APISIX | **in** |
+| `bin/`, `t/`, `example/`, `ci/`, `.github/`, demo configs | n/a | n/a | 
**out** *(maintainer — confirmed by Ming Wen 2026-05-15)* |
+| Vendored Lua runtime dependencies under `deps/` and `lua_modules/` | varies 
| varies | **in** (per apisix-master-0.rockspec runtime deps) *(maintainer — 
confirmed by Ming Wen 2026-05-15)* |
+| Test fixtures under `t/lib/` | varies | varies | **out** *(maintainer — 
confirmed by Ming Wen 2026-05-15)* |
+
+---
+
+## §4.3 Out of scope (explicit non-goals)
+
+The following are not threat-model scope. A report whose root
+cause sits here is closed as `OUT-OF-MODEL` with a pointer to the
+specific bullet below.
+
+1. **Operator misconfiguration** that voids a documented default-secure
+   posture. Examples: exposing the Admin API on `0.0.0.0` without
+   changing `admin_listen.allow_admin` from its default
+   `127.0.0.0/24`; running with the documented-as-known
+   default Admin API key `edd1c9f034335f136f87ad84b625c8f1`
+   (the `conf/config.yaml` warning calls this out explicitly).
+   *(documented — admin-api.md, conf/config.yaml:59-63)*
+2. **etcd security as such.** APISIX assumes etcd is operator-secured
+   (TLS, auth, network isolation). A finding that requires
+   compromising etcd is not an APISIX finding.
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+3. **Upstream service vulnerabilities.** APISIX routes traffic to
+   operator-chosen upstreams; bugs *in those upstreams* are out of
+   scope. *(maintainer — confirmed by Ming Wen 2026-05-15)*
+4. **Operator-supplied Lua code** (custom plugins via
+   `extra_lua_path`, `serverless-pre-function` /
+   `serverless-post-function` route-embedded code, custom external
+   plugin runners). This code is loaded into the same worker
+   process with full `ngx.*` access — by design *(documented —
+   plugin-develop.md, external-plugin.md)*. The PMC is responsible
+   for the Apache-maintained plugins under `apisix/plugins/`; the
+   operator is responsible for their own. Exception: the example
+   snippets in `docs/` are PMC responsibility — an exploitable
+   documented example is a documentation bug, triaged as
+   `VALID-HARDENING`. *(maintainer — confirmed by Ming Wen 2026-05-15)*
+5. **All plugins are opt-in; none are active without explicit
+   per-route configuration.** A plugin is only on the request hot
+   path once an operator names it in a route's `plugins:` block (or
+   in an `ApisixPluginConfig` / `ApisixRoute` CRD). There is no
+   "default-enabled plugins subset". Enabling a plugin and finding
+   a bug in it is in scope of §4.8 for any plugin shipped under
+   `apisix/plugins/`. *(maintainer — confirmed by Ming Wen 2026-05-15)*
+6. **Kubernetes cluster security** — RBAC, namespace isolation,
+   network policy, admission controllers. The ingress controller
+   assumes the cluster operator has gated who can create
+   `ApisixRoute` / `ApisixConsumer` / `ApisixPluginConfig`
+   resources (documented duty: creators of `ApisixRoute` must be
+   the namespace owner or equivalent trust tier). The
+   controller's own RBAC requirements are documented in
+   `apisix-ingress-controller/config/rbac/role.yaml`.
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+7. **Browser-host compromise.** A browser-extension stealing the
+   admin key from an operator's browser is not in scope.
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+8. **Side-channel attacks** (timing, cache, electromagnetic).
+   APISIX is a Lua/Go application; constant-time crypto at the
+   TLS layer is the responsibility of the underlying TLS stack
+   (OpenSSL via OpenResty / Go's `crypto/tls`). APISIX's own
+   credential comparisons (admin key, JWT secret, HMAC signature,
+   etc.) are expected to be constant-time — that is a §4.8
+   property, not a §4.3 exclusion. *(maintainer — confirmed by
+   Ming Wen 2026-05-15)*
+9. **Denial-of-service via resource exhaustion** of layers below
+   APISIX (kernel TCP backlog, file descriptor limit, host RAM).
+   APISIX provides rate-limiting / circuit-breaker plugins but
+   does not enforce them by default. *(maintainer — confirmed by
+   Ming Wen 2026-05-15; see §4.10)*
+10. **Code in `bin/`, `t/`, `example/`, `benchmark/`, `ci/`,
+    `.github/`** — test fixtures, smoke scripts, benchmark
+    harnesses, CI configuration. Not deployed to production.
+    `t/lib/` test fixtures are likewise out of model. *(maintainer
+    — confirmed by Ming Wen 2026-05-15)*
+
+---
+
+## §4.4 Trust boundaries and data flow
+
+**Primary trust boundaries** (where untrusted data crosses into
+the trusted core):
+
+```
+                                            (operator)
+                                                |
+                                                v
+External client --HTTPS-->  [data-plane     <--+
+(untrusted)                  worker process    |
+                             — Lua plugins,    | Admin API
+                             route table,      | (X-API-KEY)
+                             upstream pool]    |
+                                ^      |       |
+                                |      |       |
+                            (etcd      |       |
+                             config    |   [Admin
+                             reads)    |    handler]
+                                |      v       |
+                              etcd <---+---> etcd writes
+                              (operator-secured, TLS optional)
+                                                ^
+                                                |
+                                (apisix-ingress-controller,
+                                 curl / human operator)
+```
+
+*(documented — architecture-design/apisix.md, admin-api.md,
+deployment-modes.md)*
+
+**Boundary transitions:**
+
+1. **External-client → worker.** OpenResty / nginx parses the
+   HTTP message; APISIX Lua plugins then run with the parsed
+   request and may inspect / rewrite / reject. Trust transition:
+   bytes go from "untrusted network input" to "parsed Lua table
+   passed to plugin code". The parser is the foundational
+   defence; plugins after it work with already-parsed inputs.
+2. **Admin API → worker.** Admin API requires `X-API-KEY`. After
+   auth, the JSON body is validated against the resource's JSON
+   Schema before being written to etcd. Trust transition:
+   "authenticated operator input" → "schema-validated config".
+3. **etcd → worker.** Workers subscribe to etcd watches and
+   apply config changes. Trust transition: none in principle
+   — etcd content was already operator-authored or
+   Admin-API-mediated.
+4. **Ingress controller → Admin API.** The controller reads
+   Kubernetes CRDs, translates to Admin API calls signed with
+   `X-API-KEY` (configured via a Kubernetes Secret). Trust
+   transition: "Kubernetes-authorized CRD" → "Admin API call".
+
+**Reachability preconditions per family** (the test a triager
+applies to a finding before anything else):
+
+| Family | A finding here is in-model only if reachable from… |
+|---|---|
+| Data-plane Lua plugins | a client request on `node_listen` that matches a 
route that has the plugin enabled. |
+| Admin API handlers | an authenticated Admin API call from a caller inside 
`allow_admin`. |
+| etcd watch handler | an etcd write whose key is under `prefix` (default 
`/apisix`). |
+| Stream proxy | a TCP/UDP packet on `stream_proxy.*_listen`. |
+| Ingress controller | a CRD a Kubernetes RBAC-authorized user created in a 
watched namespace. |
+| External-plugin runner | the gateway worker is calling the runner via unix 
socket. |
+
+---
+
+## §4.5 Assumptions about the environment
+
+- **Operating system / runtime**: Linux is the only supported
+  production deployment target. macOS is dev/test only.
+  Windows / BSD / Solaris and other non-Linux platforms are
+  out of model; a report against a non-Linux deployment is
+  closed as `OUT-OF-MODEL: unsupported-platform`.
+  *(maintainer — confirmed by Ming Wen 2026-05-15)*
+- **Runtime**: OpenResty (nginx + LuaJIT). Plugin code runs as
+  Lua coroutines inside nginx workers. *(documented —
+  architecture-design/apisix.md)*
+- **Concurrency**: nginx multi-worker; per-worker Lua state.
+  Plugins must not assume single-worker state. *(documented —
+  plugin-develop.md notes shared-dict and `core.table.new` patterns)*
+- **Time / clock**: relies on the host clock for cache TTLs and
+  rate-limit windows. Clock-drift behaviour (JWT replay-window
+  edge cases, rate-limit window roll-over) is **out of model**;
+  NTP synchronization is an operator responsibility (see §4.10).
+  *(maintainer — confirmed by Ming Wen 2026-05-15)*
+- **Network**: data-plane port reachable by clients; Admin API
+  port restricted to operator network; etcd reachable from
+  workers; outbound from workers to upstreams + log sinks
+  (Kafka, Datadog, etc.). *(documented — admin-api.md,
+  ssl-protocol.md)*
+- **Filesystem**: APISIX reads `conf/config.yaml` and any files
+  named under `extra_lua_path`. SSL cert/key material can be
+  stored on filesystem **or** in etcd; etcd-stored keys are
+  plaintext-in-etcd by default unless etcd encryption-at-rest is
+  configured by the operator, or `apisix.data_encryption` is
+  enabled for field-level encryption. *(documented —
+  apisix/core/etcd.lua; see §4.8 point 11)*
+
+**Negative claims — what APISIX does *not* do to its host:**
+*(maintainer — confirmed by Ming Wen 2026-05-15; all 5 hold as
+written.)*
+
+- Does not require root after startup (drops to non-root worker user).
+- Does not install global signal handlers beyond what nginx itself does.
+- Does not fork persistent daemon subprocesses beyond
+  configured external-plugin runners.
+- Does not write outside `logs/` and the OpenResty / etcd cache
+  directories.
+- Does not phone home or call any vendor endpoint.
+
+---
+
+## §4.5a Build-time and configuration variants
+
+The following config knobs change which §4.8 properties hold.
+**Note:** all claims below are *(documented)* unless tagged otherwise.
+
+| Knob | Default | Effect when flipped from default | Maintainer stance |
+|---|---|---|---|
+| `deployment.admin.admin_key[].key` | `edd1c9f0…` (in docs / sample config) | 
Without changing it, the Admin API has no real auth. | **Documented as required 
to change in production.** A report against an unchanged default is 
`OUT-OF-MODEL: operator-misconfig` per §4.3. *(maintainer — confirmed by Ming 
Wen 2026-05-15)* |
+| `deployment.admin.allow_admin` | `127.0.0.0/24` | Widening to `0.0.0.0/0` 
exposes Admin API to the network. | `OUT-OF-MODEL: operator-misconfig` if 
widened and then exploited. *(maintainer — confirmed by Ming Wen 2026-05-15)* |
+| `deployment.admin.enable_admin` | `true` | `false` disables the Admin API; 
the data plane reads etcd directly (decoupled mode). | Both supported. 
Decoupled mode is recommended for internet-facing / public-edge deployments; 
traditional mode is appropriate for internal-network deployments. *(maintainer 
— confirmed by Ming Wen 2026-05-15)* |
+| `deployment.etcd.tls.{cert,key,verify}` | unset (plaintext) | Enabling TLS 
protects etcd traffic. | **Required if etcd is networked** (multi-host or 
cross-zone). Optional for single-host loopback deployments. *(maintainer — 
confirmed by Ming Wen 2026-05-15)* |
+| `apisix.ssl.listen` / `ssl_protocols` | TLS 1.2 / 1.3, no 1.0/1.1 | 
Re-enabling 1.0/1.1 weakens transport. | Documented; not recommended. 
*(documented — ssl-protocol.md)* |
+| `plugins:` list | (no enabled plugins; all opt-in) | Naming a plugin on a 
route enables it. | All plugins are opt-in; a CVE on any Apache-maintained 
plugin under `apisix/plugins/` is CVE-equivalent regardless of how widely it 
tends to be enabled in the wild. *(maintainer — confirmed by Ming Wen 
2026-05-15)* |
+| `extra_lua_path` | unset | Loading operator-supplied Lua plugins. Those are 
out of model per §4.3 point 4. | *(documented — plugin-develop.md)* |
+| `apisix.role` | `traditional` | `data_plane` / `control_plane` change which 
surface is exposed. | Documented; security implications laid out in 
deployment-modes.md. *(documented)* |
+| `apisix.data_encryption` | unset / disabled | Enables field-level encryption 
of sensitive consumer-credential fields in etcd. | Optional in 3.x; not enabled 
by default. See §4.8 point 11. *(maintainer — confirmed by Ming Wen 
2026-05-15)* |
+
+**The insecure-default case** (per the rubric): the Admin API
+ships with a documented-as-known weak key. The `conf/config.yaml`
+sample explicitly says *"using fixed API token has security
+risk, please update it when you deploy to production
+environment."* Reading **(b)** is confirmed: the default is a
+dev-convenience and operators are documented as required to flip
+it. A report that exploits the unchanged default key is
+`OUT-OF-MODEL: operator-misconfig`. *(maintainer — confirmed by
+Ming Wen 2026-05-15)*
+
+---
+
+## §4.6 Assumptions about inputs
+
+**Per-component input table** (grouped by family from §4.2).
+
+### Gateway data-plane
+
+| Endpoint / message | Field | Attacker-controllable? | Caller / operator must 
enforce |
+|---|---|---|---|
+| Any route on `node_listen` | request line (method, URI, query) | **yes** | 
route regex must not be catastrophic backtracking (project applies an 
Anti-ReDoS policy on input regex). *(documented — admin API validation)* |
+| Any route | request headers (incl. `X-Forwarded-*`) | **yes** | not to be 
trusted as authentication ground truth unless an `ip-restriction` / `real-ip` 
plugin is on. *(documented — real-ip plugin doc)* |
+| Any route | request body | **yes** | size bounded by `client_max_body_size`; 
content trusted only insofar as the route's plugins validated it. |
+| `stream_proxy` | TCP / UDP payload | **yes** | upstream is responsible for 
protocol handling; APISIX forwards bytes. |
+| TLS handshake | SNI | **yes** | SNI is used for cert selection but **not** 
treated as authenticated identity. *(documented — ssl-protocol.md)* |
+
+### Gateway control-plane (Admin API)
+
+| Endpoint | Field | Attacker-controllable? | Caller must enforce |
+|---|---|---|---|
+| `PUT /apisix/admin/routes/<id>` | `plugins.{*}.{*}` | **yes if Admin API 
exposed** | JSON-Schema validated before persist; schema must reject unsafe 
shapes. *(documented — plugin schema validation)* |
+| `PUT /apisix/admin/ssls/<id>` | `cert`, `key` | trusted (operator) | private 
key is stored in etcd; etcd security is the protective layer (see §4.8 point 11 
for optional `apisix.data_encryption`). |
+| `PUT /apisix/admin/consumers/<id>` | `username`, plugin creds | trusted 
(operator) | Stored in etcd under `/apisix/consumers/<username>`, organized per 
plugin (key-auth: `key`; jwt-auth: `key`+`secret`+`algorithm`; basic-auth: 
`username`+`password`; hmac-auth: `access_key`+`secret_key`; etc.). Optional 
field-level encryption via `apisix.data_encryption`. *(maintainer — confirmed 
by Ming Wen 2026-05-15)* |
+| `POST /apisix/admin/routes` | `script` (legacy) | trusted (operator) | 
**arbitrary Lua execution by design** — same trust posture as `extra_lua_path`. 
The `script` field is currently still present and is planned for removal in the 
next release; semantically equivalent to `extra_lua_path` (out-of-model per 
§4.3 point 4). *(maintainer — confirmed by Ming Wen 2026-05-15)* |
+
+### Ingress controller
+
+| Surface | Field | Attacker-controllable? | Cluster operator must enforce |
+|---|---|---|---|
+| `ApisixRoute.spec.http[*].plugins[*]` | plugin config | depends on RBAC | 
restrict CRD creation to trusted namespaces / users; creators of `ApisixRoute` 
must be the namespace owner or equivalent trust tier. *(maintainer — confirmed 
by Ming Wen 2026-05-15)* |
+| `ApisixConsumer.spec.plugins[*]` | credential material | depends on RBAC | 
same as above. |
+| `ApisixPluginConfig` | shared plugin block | depends on RBAC | same. |
+
+**Size, shape, rate assumptions.** Request size bounded by
+`client_max_body_size` (nginx-level; default 8KB but the project
+ships 1m). Connection rate bounded by kernel + worker_connections.
+Rate-limiting and circuit-breaker plugins are **opt-in** — APISIX
+does not rate-limit by default. *(documented — limit-req,
+limit-count, limit-concurrency plugin docs)*
+
+---
+
+## §4.7 Adversary model
+
+**Adversaries in scope.**
+
+1. **External untrusted client** — a remote network attacker
+   speaking HTTP / HTTPS / TCP / UDP / gRPC to `node_listen`.
+   They can send arbitrary, malformed, or oversized requests.
+   They aim to: bypass route auth; reach an upstream they
+   shouldn't; crash a worker; cause CPU / memory exhaustion;
+   read configured-secret material (e.g., an Authorization
+   header that another plugin sets).
+2. **Authenticated client** — a client with valid credentials
+   for **one** route or consumer, attempting to reach a route
+   or consumer they should not have access to (horizontal
+   privilege escalation through auth-plugin bugs).
+3. **Compromised plugin author** — limited to plugins shipped
+   in `apisix/plugins/`, since that's the trust boundary the
+   PMC owns. All Apache-maintained plugin bugs are CVE-equivalent;
+   since all plugins are opt-in (§4.3 point 5), there is no
+   priority differentiation between "default-loaded" and
+   "opt-in". Operator-supplied plugins are out per §4.3 point 4.
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+4. **Unprivileged Kubernetes user** with create rights on
+   `ApisixRoute` in some namespace, attempting to influence
+   traffic outside that namespace via the ingress controller.
+   The cluster operator's documented duty is to gate CRD
+   creation appropriately (§4.3 point 6). *(maintainer —
+   confirmed by Ming Wen 2026-05-15)*
+
+**Adversaries out of scope** (cross-ref §4.3):
+
+- Operator with Admin API credentials. They've already won.
+- Operator-supplied Lua code authors.
+- An attacker who has compromised etcd.
+- An attacker who has compromised the host running APISIX.
+- An attacker with physical access / hypervisor access /
+  co-tenant capabilities on the same VM.
+- A compromised log-sink endpoint. Log sinks are operator-trusted
+  infrastructure. (Sink-failure-availability and
+  malicious-sink-response resilience is a §4.8 property — see
+  point 10 — not an adversary in this section.) *(maintainer —
+  confirmed by Ming Wen 2026-05-15)*
+
+---
+
+## §4.8 Security properties the project provides
+
+For each property: the property, violation symptom, severity
+tier, provenance.
+
+1. **HTTP request parsing safety.**
+   - Property: malformed HTTP requests on `node_listen` cause
+     `400` rejection, not worker memory corruption or RCE.
+     HTTP/1.1 / HTTP/2 wire-level parsing bugs are owned by
+     upstream nginx (APISIX tracks and ships fixed versions);
+     APISIX's own Lua-phase parsing (custom header / query /
+     body handling, gRPC metadata, etc.) is APISIX-owned.
+   - Violation symptom: worker segfault / OOB read / RCE
+     triggered by request bytes.
+   - Severity: **security-critical (CVE).**
+   - Provenance: *(documented — relies on nginx's parser; project
+     does not duplicate parsing)*; *(maintainer — confirmed by
+     Ming Wen 2026-05-15: layered ownership)*.
+
+2. **Admin API authentication gate.**
+   - Property: any Admin API call without a valid
+     `X-API-KEY` (matching `admin_key[].key`) returns 401 and
+     does not mutate state.
+   - Violation symptom: an unauthenticated request modifies a
+     route or reads a consumer secret.
+   - Severity: **security-critical (CVE).**
+   - Provenance: *(documented — admin-api.md, t/admin/api.t)*.
+
+3. **Admin API IP allowlist.**
+   - Property: a request from outside
+     `deployment.admin.allow_admin` is rejected at network level
+     (returns 403 or connection refused).
+   - Violation symptom: Admin API reachable from disallowed CIDR.
+   - Severity: security-critical (CVE) if bypassed; operator
+     misconfiguration if widened intentionally.
+   - Provenance: *(documented — config.yaml comments)*.
+
+4. **JSON-Schema validation of plugin configs.**
+   - Property: the Admin API rejects plugin configs that fail
+     the plugin's published JSON Schema; only schema-conformant
+     configs are written to etcd.
+   - Violation symptom: a config that violates the schema is
+     accepted, then crashes the worker at apply time.
+   - Severity: high (denial-of-service via crash); CVE if it
+     escalates to RCE.
+   - Provenance: *(documented — plugin.lua schema-validation
+     path)*.
+
+5. **TLS termination.**
+   - Property: APISIX terminates TLS using configured ciphersuites
+     in line with `ssl_protocols`; TLS 1.0 / 1.1 disabled by
+     default.
+   - Violation symptom: SSL/TLS downgrade or cert mis-selection
+     under SNI.
+   - Severity: high (CVE for cipher / protocol bypass).
+   - Provenance: *(documented — ssl-protocol.md)*.
+
+6. **Plugin chain authorization.**
+   - Property: each plugin runs in the configured phase order;
+     a plugin cannot suppress later auth plugins from running
+     unless documented to (e.g., `serverless-pre-function`,
+     which is by design able to rewrite, short-circuit, or
+     bypass later auth plugins — operators enabling it take on
+     responsibility for the resulting trust model, concrete
+     instance of §4.3 point 4).
+   - Violation symptom: a plugin's misordering causes an
+     unauthenticated request to reach the upstream.
+   - Severity: security-critical (CVE).
+   - Provenance: *(documented — plugin.lua phase chain)*;
+     *(maintainer — confirmed by Ming Wen 2026-05-15:
+     `serverless-*` interactions are by design)*.
+
+7. **Rate-limit / circuit-break plugin integrity.**
+   - Property: when `limit-req` / `limit-count` /
+     `limit-concurrency` are configured, their counters are
+     consulted on the request hot path and exceeding the limit
+     yields `503` / `429` (per config).
+   - Violation symptom: a counter is bypassed; an attacker
+     achieves > N requests per window despite a configured limit.
+   - Severity: high (DoS) or critical (depending on what the
+     limit gated).
+   - Provenance: *(documented — limit-req.md, limit-count.md)*.
+
+8. **Ingress-controller fidelity.**
+   - Property: every field accepted by an `apisix.apache.org`
+     CRD spec maps to a defined Admin API target. Silent drop,
+     injection, or renaming is an `apisix-ingress-controller`
+     bug — not operator misconfiguration. An e2e contract test
+     enforcing this invariant is recommended.
+   - Violation symptom: controller injects fields the CRD did
+     not request; or controller silently drops a field that
+     was required for security.
+   - Severity: security-critical if a drop voids an auth-plugin
+     configuration.
+   - Provenance: *(maintainer — confirmed by Ming Wen 2026-05-15)*.
+
+9. **Constant-time comparison of credentials.**
+   - Property: APISIX's own credential comparisons — admin key,
+     JWT secret, HMAC signature, and equivalent secrets stored
+     by auth plugins — use constant-time comparison so that
+     remote timing cannot be used to recover the secret. (TLS-
+     layer side channels remain out of model and are delegated
+     to OpenSSL / Go `crypto/tls`.)
+   - Violation symptom: a measurable timing oracle on `X-API-KEY`,
+     JWT verification, HMAC verification, etc.
+   - Severity: high (credential disclosure).
+   - Provenance: *(maintainer — confirmed by Ming Wen 2026-05-15;
+     §4.14 q-5)*.
+
+10. **Log-sink failure / malicious-response resilience.**
+    - Property: a slow, failed, or actively malicious log-sink
+      endpoint (Kafka / Datadog / Splunk / HTTP logger) must
+      not impact APISIX availability — no worker hang, no RCE,
+      no segfault triggered by sink-side bytes.
+    - Violation symptom: a worker hangs / crashes / executes
+      attacker-controlled code as a result of bytes returned by
+      a log-sink endpoint.
+    - Severity: high (DoS) or critical (RCE).
+    - Provenance: *(maintainer — confirmed by Ming Wen 2026-05-15;
+      §4.14 q-17)*.
+
+11. **Optional field-level encryption of sensitive consumer
+    fields (`apisix.data_encryption`).**
+    - Property: when `apisix.data_encryption` is enabled (3.x;
+      not enabled by default), sensitive fields in consumer /
+      ssl resources are encrypted before being written to etcd.
+    - Violation symptom: with the knob enabled, the protected
+      field is still readable in plaintext in etcd.
+    - Severity: high (credential disclosure if etcd is observed).
+    - Provenance: *(maintainer — confirmed by Ming Wen 2026-05-15;
+      §4.14 q-14)*.
+
+<!-- §4.8 point 9 (former "Dashboard does not persist the admin key") removed
+in the 2026-05-30 revision because apisix-dashboard is out of current scan
+scope (PMC decision 2026-05-26; see §4.11a and §4.14 q-21). Re-add this
+property as a §4.8 line when dashboard re-enters scope. -->
+
+---
+
+## §4.9 Security properties the project does NOT provide
+
+1. **Default-strong Admin API key** — APISIX ships a documented
+   weak default; operators must rotate. *(documented — see §4.5a)*
+2. **etcd-side encryption / authentication by default** —
+   etcd ships unauth and plaintext; operator's responsibility.
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+3. **CSRF protection on the Admin API.** The Admin API uses
+   `X-API-KEY`-header auth, not session cookies; CSRF as
+   typically understood is not the threat. But: a malicious
+   page loaded in the operator's browser cannot directly read
+   Admin API responses (same-origin) unless the operator has
+   widened CORS — APISIX does not set permissive CORS by
+   default. *(maintainer — confirmed by Ming Wen 2026-05-15)*
+4. **Plugin sandboxing** — Lua plugins run in the same worker
+   process with full `ngx.*` access; external-plugin runners
+   inherit the APISIX uid. A compromised in-tree plugin is RCE
+   in the gateway. *(documented — plugin-develop.md,
+   external-plugin.md)*
+5. **RBAC on the Admin API.** The Admin API has a single global
+   admin role; there is no fine-grained read-only vs write
+   distinction, no per-resource ACL. *(documented — admin-api.md)*
+6. **Audit log of Admin API changes.** APISIX itself does not
+   emit a structured audit log of Admin API mutations; operators
+   wire one externally (access-log on the Admin API listener
+   combined with `kafka-logger` / `http-logger` to a SIEM —
+   see §4.10). *(maintainer — confirmed by Ming Wen 2026-05-15)*
+7. **Rate-limit on the Admin API.** The data-plane rate-limit
+   plugins do not protect the Admin API; operator must front
+   the Admin API with firewall / WAF / fail2ban (see §4.10).
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+8. **Prevention of operator-supplied plugin RCE.** By design;
+   see §4.3 point 4.
+
+---
+
+## §4.10 Downstream responsibilities
+
+What the operator must do to inherit the §4.8 properties:
+
+1. **Change the Admin API key** from the documented default,
+   and store it outside `config.yaml` (env var, K8s Secret,
+   external secret manager). *(documented)*
+2. **Restrict `allow_admin`** to operator workstations or
+   bastions; do not widen to `0.0.0.0/0`. *(documented)*
+3. **Run etcd with TLS + auth** if etcd is on a network reachable
+   by anything other than the APISIX worker — required when
+   networked (multi-host or cross-zone); optional for
+   single-host loopback. Configure
+   `deployment.etcd.tls.{cert,key,verify}` accordingly.
+   *(maintainer — confirmed by Ming Wen 2026-05-15)*
+4. **Audit operator-supplied plugins** (`extra_lua_path`,
+   serverless-pre/post, external plugin runners) before deploy
+   — this code is in the trusted-by-design tier. *(documented)*
+5. **Configure rate-limiting + circuit-breaker plugins** for
+   any production-facing route; APISIX does not impose these by
+   default. *(documented)*
+6. **Use decoupled mode** (separate `data_plane` / `control_plane`
+   roles, or `standalone` mode) for any internet-facing /
+   public-edge deployment; this removes the Admin API from the
+   data-plane's blast radius. Traditional mode remains
+   appropriate for internal-network deployments. *(maintainer
+   — confirmed by Ming Wen 2026-05-15)*
+7. **Restrict Kubernetes RBAC** so that only trusted
+   service-accounts / users can create `ApisixRoute` /
+   `ApisixConsumer` / `ApisixPluginConfig` CRDs. Documented
+   duty: creators of `ApisixRoute` must be the namespace
+   owner or equivalent trust tier. *(maintainer — confirmed
+   by Ming Wen 2026-05-15)*
+8. **Choose TLS configuration consciously**: at minimum the
+   defaults (TLS 1.2 / 1.3); enable mTLS for client-cert auth
+   where required. *(documented)*
+9. **Synchronize the host clock (NTP).** Clock-drift behaviour
+   of JWT replay windows and rate-limit window roll-over is
+   not an APISIX security violation — operator must keep host
+   time in sync. *(maintainer — confirmed by Ming Wen 2026-05-15;
+   §4.14 q-8)*
+10. **Wire Admin-API audit logging externally.** APISIX does not
+    emit a structured admin-mutation audit log; operators
+    combine access-log on the Admin API listener with
+    `kafka-logger` / `http-logger` to a SIEM. *(maintainer —
+    confirmed by Ming Wen 2026-05-15; §4.14 q-22)*
+11. **Front the Admin API with firewall / WAF / fail2ban.**
+    Data-plane rate-limit plugins do not protect the Admin API
+    — operator must add a rate-limit / brute-force defence
+    layer in front of it. *(maintainer — confirmed by Ming Wen
+    2026-05-15; §4.14 q-23)*
+12. **Strip the `Server: APISIX/x.y.z` banner if banner-grabbing
+    is a concern.** Use the `response-rewrite` plugin or a
+    custom `error_page` directive. (Version disclosure via
+    default error page is itself a `KNOWN-NON-FINDING` — see
+    §4.11a — but operators who want to harden against it have
+    a documented path.) *(maintainer — confirmed by Ming Wen
+    2026-05-15; §4.14 q-27)*
+
+---
+
+## §4.11 Known misuse patterns
+
+Each is a pattern the PMC has seen often enough to warrant a
+heads-up. *(maintainer — confirmed by Ming Wen 2026-05-15: all
+7 below match PMC experience.)*
+
+1. Running with the documented-as-weak Admin API key in
+   production. (The doc literally warns against it; reports here
+   are not findings.)
+2. Putting the Admin API on `0.0.0.0` with the default
+   `allow_admin` widened to `0.0.0.0/0`.
+3. Running etcd unauthenticated and reachable from anything
+   other than the worker host.
+4. Loading operator-supplied Lua via `extra_lua_path` or
+   `serverless-pre-function` without an internal review.
+5. Treating `X-Forwarded-For` / `X-Real-IP` as authenticated
+   identity without the `real-ip` plugin or the equivalent
+   upstream-PROXY-protocol handling.
+6. Storing SSL private keys in etcd without etcd encryption-at-rest
+   or TLS (and without enabling `apisix.data_encryption`).
+7. Single shared admin key across multiple operators (no
+   per-operator key, no audit trail).
+
+---
+
+## §4.11a Known non-findings (recurring false positives)
+
+*(maintainer — confirmed by Ming Wen 2026-05-15: all 8 below are
+consistent with the PMC's historical security-report archive.)*
+
+1. **Hardcoded default Admin API key in `conf/config.yaml`** —
+   intentional dev-convenience; flagged in the same file's
+   comment. Reports: `OUT-OF-MODEL: operator-misconfig`.
+2. **`X-API-KEY`-style header auth on the Admin API** — the
+   project's auth scheme by design. Reports asking "why not
+   OAuth?" are `OUT-OF-MODEL: by-design`.
+3. **Operator-supplied Lua executes in the worker** — by design,
+   see §4.3 point 4.
+4. **etcd plaintext-by-default** — operator-responsibility per
+   §4.10 point 3.
+5. **Plugin runs in same process as gateway core** — by design
+   per §4.9 point 4.
+6. **No CSRF tokens on Admin API** — the Admin API uses header
+   auth, not cookie auth; not CSRF-applicable in the usual sense.
+   (See §4.9 point 3 for nuance.)
+7. **Version disclosure** in default error pages / responses
+   — common ASF stance; operators harden via custom error
+   pages or `response-rewrite` (see §4.10 point 12).
+   *(maintainer — confirmed by Ming Wen 2026-05-15: confirmed
+   `KNOWN-NON-FINDING`.)*
+8. **OUT-OF-SCOPE: `apache/apisix-dashboard`.** The dashboard
+   is excluded from the current scan run per the PMC's
+   2026-05-26 message. Findings against the dashboard repo
+   are not part of this model. The previously-tracked
+   localStorage admin-key persistence finding (q-21) is being
+   addressed in a separate PR against `apache/apisix-dashboard`
+   (`atomWithStorage` → `atom` change). When the dashboard
+   re-enters scan scope, §4.8 will regain its "dashboard does
+   not persist the admin key" property.
+
+---
+
+## §4.12 Conditions that would change this model
+
+- New deployment role (e.g., a future `gateway_dashboard_unified`
+  mode where the dashboard is served by APISIX itself).
+- New auth plugin that grants partial Admin API access (would
+  require revisiting §4.9 point 5).
+- Dropping or strengthening the Anti-ReDoS policy on route
+  regexes.
+- A new external-plugin protocol that drops the same-uid
+  assumption.
+- Re-inclusion of `apache/apisix-dashboard` in scan scope (would
+  restore the dashboard-related §4.8 property and the
+  dashboard-specific §4.2 / §4.6 rows).
+
+---
+
+## §4.13 Triage dispositions
+
+A report against any of the in-scope repos is closed under one
+of these labels. *(maintainer — confirmed by Ming Wen 2026-05-15:
+the 9 dispositions below are sufficient; no additions or removals.)*
+
+| Disposition | When | Body of reply |
+|---|---|---|
+| `VALID` | violates a §4.8 property; reachable per §4.4. | Acknowledged; 
coordinated disclosure timeline; fix planned for release. |
+| `VALID-HARDENING` | not a §4.8 violation but tightens a §4.9 property in a 
way the PMC accepts (includes exploitable `docs/` example snippets). | 
Acknowledged; lower priority; may merge as hardening PR. |
+| `OUT-OF-MODEL: operator-misconfig` | the issue is an instance of §4.3 point 
1 or §4.11 (operator widened a default, did not rotate the admin key, ran etcd 
unauth, etc.). | Cite the relevant §4.5a / §4.10 row. |
+| `OUT-OF-MODEL: trusted-input` | report supplies attacker-controlled bytes 
through a parameter the §4.6 table marks "not attacker-controllable" (e.g., a 
`format` literal, a plugin's `script` field — note that the `script` example is 
valid until the next-release removal lands, per §4.14 q-15). | Cite the §4.6 
row. |
+| `OUT-OF-MODEL: adversary-not-in-scope` | the threat requires capabilities 
the §4.7 adversary doesn't have (operator credentials, etcd compromise, host 
compromise, side-channel, compromised log sink). | Cite the §4.7 adversary 
list. |
+| `OUT-OF-MODEL: out-of-tree-code` | finding is in operator-supplied Lua / 
external-plugin code / a vendored library that is itself out of model. | Cite 
§4.3 point 4 or §4.2 component-family table. |
+| `OUT-OF-MODEL: unsupported-platform` | report is against a non-Linux 
deployment (macOS dev/test, Windows, BSD, etc.). | Cite §4.5 OS row. |
+| `BY-DESIGN: property-disclaimed` | finding hits an explicit §4.9 
non-property (no plugin sandbox, no RBAC, etc.). | Cite the §4.9 line. |
+| `KNOWN-NON-FINDING` | exact match to a §4.11a entry. | Cite §4.11a line; 
one-paragraph reply. |
+| `MODEL-GAP` | the report describes a real bug, but this document does not 
have a §4.8 property covering it. | The PMC will decide whether to add a §4.8 
line (turning into `VALID`) or a §4.9 line (turning into `BY-DESIGN`). |
+
+<!-- The unsupported-platform row was promoted to a first-class disposition
+during the §4.14 q-7 confirmation pass (2026-05-15). -->
+
+---
+
+## §4.14 Open Questions for the Maintainers — RESOLVED
+
+All 28 open questions raised in the 2026-05-15 draft were answered
+by the PMC (Ming Wen, 2026-05-15). The corresponding *(inferred)*
+tags in the body have been promoted to *(maintainer — confirmed
+by Ming Wen 2026-05-15)*. The answer summaries are kept below for
+traceability.
+
+1. **(§4.2 vendored libs)** `deps/` and `lua_modules/` are
+   in-model — APISIX runtime dependencies per
+   `apisix-master-0.rockspec`. `t/lib/` is out-of-model (test
+   fixtures).
+2. **(§4.3 point 4 / `docs/`)** Operator-supplied Lua is out-of-
+   model. Exception: `docs/` example snippets are PMC
+   responsibility — an exploitable documented example is a
+   documentation bug triaged as `VALID-HARDENING`.
+3. **(§4.5a plugins list)** All plugins are disabled by default.
+   No plugin processes traffic without explicit operator
+   configuration on a route. The "default-enabled subset"
+   framing has been removed everywhere.
+4. **(K8s RBAC)** Controller's own RBAC requirements are
+   documented in
+   `apisix-ingress-controller/config/rbac/role.yaml`. Cluster
+   operator's duty: creators of `ApisixRoute` must be the
+   namespace owner or equivalent trust tier.
+5. **(Side channels)** TLS-layer side channels are out-of-model
+   (delegated to OpenSSL / Go `crypto/tls`). APISIX's own
+   credential comparisons must be constant-time — added as
+   §4.8 point 9.
+6. **(`bin/`, `t/`, etc.)** `ci/` and `.github/` added to the
+   out-of-model directory list (§4.3 point 10).
+7. **(OS)** Linux is the only supported production target.
+   macOS is dev/test only. A report against a non-Linux
+   deployment is closed as `OUT-OF-MODEL: unsupported-platform`
+   (§4.13).
+8. **(Clock drift)** Out-of-model. NTP sync is an operator
+   responsibility (§4.10 point 9). JWT replay-window edge
+   cases and rate-limit window roll-over are not APISIX
+   security violations.
+9. **(Negative claims)** All 5 negative claims hold as written.
+10. **(`allow_admin` widening)** `OUT-OF-MODEL:
+    operator-misconfig`. Same rationale as the default admin
+    key.
+11. **(Deployment modes)** Both modes supported. Decoupled
+    mode recommended for internet-facing deployments;
+    traditional mode appropriate for internal-network
+    deployments.
+12. **(etcd TLS)** Required when etcd is networked
+    (`deployment.etcd.tls.{cert,key,verify}`). Optional for
+    single-host loopback. Added to §4.10 point 3.
+13. **(Admin-key default)** Reading **(b)** confirmed:
+    `OUT-OF-MODEL: operator-misconfig`. See §4.5a.
+14. **(Consumer credentials)** Stored in etcd under
+    `/apisix/consumers/<username>`, per-plugin. Optional
+    `apisix.data_encryption` for field-level encryption in 3.x
+    (not enabled by default). Added as §4.8 point 11.
+15. **(`script` field)** Currently present on
+    `apisix/admin/routes`; planned for removal in the next
+    release. Semantically equivalent to `extra_lua_path` (out-
+    of-model per §4.3 point 4). The §4.13 `OUT-OF-MODEL:
+    trusted-input` example using `script` stays until the
+    next-release removal lands.
+16. **(Plugin author trust)** All Apache-maintained plugin
+    bugs are CVE-equivalent. No "default-loaded" vs "opt-in"
+    distinction — since all plugins are opt-in (q-3), the
+    distinction does not apply.
+17. **(Log sinks)** Operator-trusted; "compromised log-sink
+    endpoint" removed from §4.7 adversary list. Sink-failure-
+    availability resilience added as §4.8 point 10.
+18. **(Parser bugs)** Layered: HTTP/1.1 + HTTP/2 wire-level
+    bugs → upstream nginx; APISIX's own Lua-phase parsing →
+    APISIX-owned. Folded into §4.8 point 1.
+19. **(`serverless-*` interactions)** By-design.
+    `serverless-pre-function` can rewrite / short-circuit /
+    bypass later auth plugins; concrete instance of §4.3
+    point 4. Folded into §4.8 point 6.
+20. **(Controller fidelity)** §4.8 commitment. Every CRD spec
+    field maps to a defined Admin API target; silent drop /
+    injection / rename is a controller bug. E2e contract test
+    recommended. Folded into §4.8 point 8.
+21. **(Dashboard key storage)**
+    `KNOWN-NON-FINDING-for-current-scope`: dashboard is OUT
+    OF SCAN SCOPE per PMC decision 2026-05-26; the
+    localStorage admin-key persistence finding is tracked in
+    a separate PR against `apache/apisix-dashboard`
+    (`atomWithStorage` → `atom` change). Re-add the
+    in-memory-only property to §4.8 only when dashboard
+    re-enters scope. See §4.11a point 8.
+22. **(Audit log)** Out-of-model; operator-wired (§4.10 point
+    10). Folded into §4.9 point 6.
+23. **(Admin-API rate-limit)** Out-of-model; operator-fronted
+    (§4.10 point 11). Folded into §4.9 point 7.
+24. **(Dashboard multi-tenant)** Out-of-scope. The dashboard
+    is a single-admin-key, fully-privileged tool; multi-
+    operator / audited use requires external SSO + Admin API
+    RBAC (RBAC not provided — §4.9 point 5). With the
+    dashboard out of current scan scope (§4.11a point 8),
+    this question is dormant for the current scan run.
+25. **(Misuse patterns)** All 7 listed misuse patterns match
+    PMC experience. No additions.
+26. **(Known non-findings)** All originally-listed non-
+    findings are consistent with PMC's historical archive.
+    Entry 8 (dashboard out-of-scope) added in this revision.
+27. **(Version disclosure)** Confirmed `KNOWN-NON-FINDING`.
+    Operator hardening via `response-rewrite` / `error_page`
+    added to §4.10 point 12.
+28. **(Triage dispositions)** The 9 dispositions are
+    sufficient. The `unsupported-platform` row was promoted
+    to a first-class entry on the same pass (per q-7).
+
+---
+
+*Revision 2026-05-30 — all originally-inferred claims resolved;
+scope reduced to `apache/apisix` + `apache/apisix-ingress-controller`
+per PMC 2026-05-26 decision (apisix-dashboard tracked separately).*

Reply via email to