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

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


The following commit(s) were added to refs/heads/master by this push:
     new c63d0e82efc [DOC] Clarify internal RPC trust boundary in threat model 
(#18504)
c63d0e82efc is described below

commit c63d0e82efc2ed1a66f2d231418dedf090b32339
Author: Haonan <[email protected]>
AuthorDate: Mon Aug 24 09:56:17 2026 +0800

    [DOC] Clarify internal RPC trust boundary in threat model (#18504)
    
    * Clarify AINode RPC trust boundary
    
    * Document core internal service ports
---
 THREAT_MODEL.md | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md
index 4f9a5421d1c..4191f5e07d8 100644
--- a/THREAT_MODEL.md
+++ b/THREAT_MODEL.md
@@ -29,11 +29,11 @@ limitations under the License.
 ## §2 Scope and intended use
 
 - **Primary use:** an operator-deployed time-series database server, written 
to by IoT/device data pipelines and read by analytics clients, over the 
network. IoTDB should generally be treated as operator-deployed infrastructure, 
deployed inside a **trusted network by default**, with the 
application/ingestion tier in front of it. *(maintainer — HTHou: "IoTDB should 
generally be treated as operator-deployed infrastructure … 
trusted-network-by-default")*
-- **Deployment shapes:** standalone single-node, and a distributed cluster 
(ConfigNode + DataNode roles, inter-node consensus). *(documented — repo 
`CLAUDE.md`)*
+- **Deployment shapes:** standalone single-node, and a distributed cluster 
(ConfigNode + DataNode roles, optional AINode for model execution, 
inter-node/control-plane RPC, and consensus). *(documented — repo `CLAUDE.md`)*
 - **Caller roles** (this is a network service, not an in-process library — the 
"caller" splits):
   - **client** — connects over the Thrift session protocol / JDBC / SQL; 
authenticates with a username/password and is constrained by RBAC privileges. 
Treated as **untrusted** beyond its granted privileges. The authenticated 
client RPC surface is the main in-model boundary. *(maintainer — HTHou: "the 
client RPC surface as the main in-model boundary")*
   - **operator/admin** — the `root` superuser and whoever controls the 
deployment, configs, and the host. **Trusted** for the instance. *(inferred)*
-  - **peer node** — another ConfigNode/DataNode in the same cluster, 
authenticated into the cluster. Trusted to the extent the cluster security 
model trusts members. *(inferred)*
+  - **peer node** — another ConfigNode/DataNode/AINode in the same cluster, 
authenticated or configured as part of the cluster. Trusted to the extent the 
cluster security model trusts members. *(inferred)*
 
 **Component-family table** *(in/out = in/out of this model; all rows inferred 
unless noted)*:
 
@@ -41,7 +41,7 @@ limitations under the License.
 | --- | --- | --- | --- |
 | Client RPC / session + SQL/query engine | Thrift session protocol 
(`iotdb-protocol/thrift-datanode`), JDBC, SQL | network (listens), filesystem 
(TsFile) | **In** *(documented: Thrift modules exist; maintainer: main in-model 
boundary)* |
 | Authentication / RBAC | login + privilege checks (Users/Roles/Privileges) | 
— | **In** *(documented)* |
-| Cluster control + consensus | ConfigNode RPC, inter-node consensus 
(`thrift-confignode`, `thrift-consensus`) | network (inter-node) | **In** 
*(documented: modules exist; trust posture inferred)* |
+| Cluster control + data exchange + consensus + AINode RPC | 
ConfigNode/DataNode internal RPC, DataNode MPP data exchange, 
ConfigNode/DataNode↔AINode RPC, inter-node consensus (`thrift-confignode`, 
`thrift-ainode`, `thrift-consensus`) | network (inter-node/control plane) | 
**In** *(documented: modules exist; trust posture inferred)* |
 | Extension / server-side execution | UDF (`USE_UDF`), Triggers 
(`USE_TRIGGER`), Pipe (`USE_PIPE`), Models/AINode (`USE_MODEL`), templates | 
runs user-supplied logic/JARs; Pipe opens network | **In, but see §9** 
*(documented: privileges exist; maintainer: grantable system privileges, RBAC 
is the boundary)* |
 | REST API / MQTT ingestion | HTTP REST service, MQTT broker (if enabled) | 
network (listens) | **In if enabled; both disabled by default** *(maintainer — 
HTHou: `enable_rest_service=false`, `enable_mqtt_service=false`)* |
 | TsFile on-disk format | `apache/tsfile` (separate repo) | filesystem | 
**Out** — separate repo, model separately *(documented: TsFile is a separate 
project)* |
@@ -60,11 +60,27 @@ limitations under the License.
 ## §4 Trust boundaries and data flow
 
 - **Primary trust boundary: the authenticated client RPC surface.** This is 
the main in-model boundary. Bytes arriving over the Thrift session protocol 
(and any enabled REST/MQTT endpoint) from a client are untrusted; a client is 
constrained to its RBAC-granted privileges. The query engine, schema engine, 
and storage layer sit behind this boundary. *(maintainer — HTHou: "the client 
RPC surface as the main in-model boundary")*
-- **Secondary boundary: the cluster/inter-node surface.** ConfigNode↔DataNode 
RPC and the consensus channel are assumed to run on a **trusted network**. 
These channels currently have **no transport encryption**; a finding that 
requires intercepting or modifying inter-node traffic is therefore 
`OUT-OF-MODEL: adversary-not-in-scope` under this posture, and operators are 
responsible for network segmentation (§10). *(maintainer — JackieTien97)*
+- **Secondary boundary: the cluster/inter-node surface.** ConfigNode/DataNode 
internal RPC, DataNode MPP data exchange, ConfigNode/DataNode↔AINode RPC, and 
the consensus channels are assumed to run on a **trusted network**. These 
channels currently have **no transport encryption**; a finding that requires 
direct access to, or interception/modification of, these internal channels is 
therefore `OUT-OF-MODEL: adversary-not-in-scope` under this posture, and 
operators are responsible for netw [...]
+
+  The core internal endpoints covered by this boundary are:
+
+  | Node | Configuration | Default port | Purpose |
+  | --- | --- | --- | --- |
+  | ConfigNode | `cn_internal_port` | `10710` | ConfigNode internal RPC and 
node registration/control |
+  | ConfigNode | `cn_consensus_port` | `10720` | ConfigNode consensus 
communication |
+  | DataNode | `dn_internal_port` | `10730` | DataNode internal RPC |
+  | DataNode | `dn_mpp_data_exchange_port` | `10740` | Distributed-query data 
exchange between DataNodes |
+  | DataNode | `dn_schema_region_consensus_port` | `10750` | SchemaRegion 
consensus communication |
+  | DataNode | `dn_data_region_consensus_port` | `10760` | DataRegion 
consensus communication |
+  | AINode | `ain_rpc_port` | `10810` | AINode internal RPC used by 
ConfigNode/DataNode clients |
+
+  `dn_rpc_port=6667` remains the client-facing Thrift/session endpoint and is 
part of the primary boundary, not this internal boundary. 
`ain_cluster_ingress_port=6667` configures the DataNode endpoint that AINode 
connects to; it does not create another AINode listener. Optional REST, MQTT, 
Prometheus, Pipe Air Gap, and extension-provided listeners are separate 
surfaces and are not included in this core internal-port list. *(documented — 
`iotdb-system.properties.template`, `iotdb-ainode.p [...]
+
 - **Reachability preconditions per component** (the test a triager applies 
before anything else):
   - A finding in the query/SQL/schema engine is **in-model** only if reachable 
from a client operating *within its granted privileges* (or from an 
unauthenticated pre-login surface). *(inferred)*
   - A finding requiring an already-`root`/admin session is **out-of-model: 
trusted-input** unless it crosses into host compromise the operator didn't 
already have. *(inferred)*
   - A finding in UDF/Trigger/Pipe/Model execution is in-model only subject to 
the §9 ruling: these are grantable system privileges, so the question is 
whether the principal granted them is trusted for that server-side execution 
capability (RBAC is the boundary, not a sandbox). *(maintainer — HTHou: see §9)*
+  - A finding requiring direct access to a core internal endpoint listed above 
is **out-of-model**: these endpoints run on the trusted cluster/control-plane 
network by posture, so direct exposure to an untrusted network is an 
unsupported deployment configuration. *(maintainer — JackieTien97; AINode RPC 
classification clarified here)*
   - A finding on the inter-node channel is **out-of-model**: the channel runs 
on a trusted network by posture (no transport encryption today), so a finding 
requiring interception/modification of inter-node traffic is `OUT-OF-MODEL: 
adversary-not-in-scope`. *(maintainer — JackieTien97)*
 
 ## §5 Assumptions about the environment
@@ -84,7 +100,8 @@ Knobs that change which security properties hold:
 - **REST API — disabled by default** (`enable_rest_service=false`). In-model 
only when the operator has explicitly enabled it. *(maintainer — HTHou)*
 - **MQTT — disabled by default** (`enable_mqtt_service=false`). In-model only 
when explicitly enabled. *(maintainer — HTHou)*
 - **Client Thrift SSL — available but disabled by default** 
(`enable_thrift_ssl=false`). Transport confidentiality/integrity on the client 
channel is therefore off unless the operator turns it on; see §9/§10. 
*(maintainer — HTHou)*
-- **Inter-node TLS / wire encryption** — **none today**; the 
ConfigNode↔DataNode and consensus channels have no transport encryption, so 
operators rely on network segmentation (§10). *(maintainer — JackieTien97)*
+- **Inter-node/internal RPC TLS / wire encryption** — **none today**; the 
ConfigNode/DataNode internal RPC, MPP data exchange, AINode RPC, and consensus 
channels have no transport encryption, so operators rely on network 
segmentation (§10). *(maintainer — JackieTien97)*
+- **AINode RPC bind/port** — the default AINode configuration binds 
`ain_rpc_address=127.0.0.1` and `ain_rpc_port=10810`; the container entrypoint 
may configure `0.0.0.0:10810` for cluster networking. This is an internal 
cluster/control-plane endpoint, not a client-facing surface. Exposing it to an 
untrusted network changes the deployment posture and is out-of-model under 
§3/§7. *(documented — 
`iotdb-core/ainode/resources/conf/iotdb-ainode.properties`, 
`docker/src/main/ainode-entrypoint.sh`)*
 - **UDF / Trigger / Pipe / AINode-model execution** — gated by grantable 
system privileges (`USE_UDF`/`USE_TRIGGER`/`USE_PIPE`/`USE_MODEL`); see §9. 
*(maintainer — HTHou)*
 - **Whitelist / network bind** (bind address, client allow-list) defaults. 
*(inferred)*
 
@@ -99,7 +116,8 @@ Per-surface trust table *(inferred unless noted; REST/MQTT 
rows apply only when
 | REST API (only if enabled; default off) | HTTP body, headers, auth | **yes** 
| TLS, auth, network exposure |
 | MQTT (only if enabled; default off) | topic, payload | **yes** | auth, 
network exposure |
 | UDF / Trigger / Pipe / Model registration | JAR / class / model artifact | 
**yes if the relevant grantable system privilege is held** | who may hold 
`USE_UDF`/`USE_TRIGGER`/`USE_PIPE`/`USE_MODEL` — those principals are trusted 
for server-side execution |
-| Inter-node RPC / consensus | peer messages | **yes if the cluster network is 
exposed** | trusted network or mutual auth |
+| AINode internal RPC | model registration, loading, and control/inference 
requests | **yes if the trusted cluster/control-plane network is exposed** | 
trusted network, cluster membership, and network segmentation |
+| Inter-node RPC / MPP data exchange / consensus | peer messages and 
distributed-query data | **yes if the cluster network is exposed** | trusted 
network or mutual auth |
 | Config files, JVM flags, data dir | local | no — operator-trusted | 
filesystem permissions |
 
 - **Shape/rate:** whether the server bounds per-query CPU/memory, result-set 
size, or concurrent sessions — and the line between a bug and operator-managed 
capacity — is set in §8 (resource line) and confirmed by the PMC; see §8/§9. 
*(maintainer — HTHou: see resource line)*
@@ -108,7 +126,7 @@ Per-surface trust table *(inferred unless noted; REST/MQTT 
rows apply only when
 
 - **Primary adversary:** a network client that can reach the IoTDB RPC port 
(or an enabled REST/MQTT port) **from within the trusted-network deployment 
posture** — either **unauthenticated** (pre-login) or **authenticated with 
limited privileges** — trying to read/write data outside its grants, escalate 
privilege, execute code on the server beyond its granted extension privileges, 
crash/exhaust the server via malformed/pre-auth input, or move laterally to 
peer nodes. *(maintainer for the [...]
 - **Capabilities assumed:** can open connections, send arbitrary protocol/SQL 
bytes, supply large/malformed payloads, and (if granted the relevant privilege) 
register extensions. *(inferred)*
-- **Out of scope:** anyone with `root`/admin session or 
host/process/filesystem control (already authoritative); an attacker who only 
reaches the server because it was directly publicly exposed (non-supported 
posture, §3); side-channel/timing adversaries (unless the PMC wants them in). 
*(maintainer for public-exposure exclusion — HTHou; rest inferred)*
+- **Out of scope:** anyone with `root`/admin session or 
host/process/filesystem control (already authoritative); an attacker who only 
reaches the server because it was directly publicly exposed (non-supported 
posture, §3); an attacker who reaches a core internal endpoint listed in §4 
from outside the trusted cluster/control-plane network; side-channel/timing 
adversaries (unless the PMC wants them in). *(maintainer for public-exposure 
exclusion — HTHou; AINode RPC classification clarified [...]
 - **Cluster — authenticated-but-Byzantine peer:** cluster membership is 
assumed **fully trusted**. IoTDB does **not** claim Byzantine fault tolerance — 
there is no safety/liveness guarantee against an authenticated-but-malicious 
peer node. A finding that requires a cluster member to behave arbitrarily is 
out-of-model under this posture. *(maintainer — JackieTien97)*
 
 ## §8 Security properties the project provides
@@ -125,7 +143,7 @@ Per-surface trust table *(inferred unless noted; REST/MQTT 
rows apply only when
 *(The highest-value section for integrators — inferred unless tagged, confirm 
each.)*
 
 - **Server-side code execution via extensions is by-design, not a 
vulnerability — gated by RBAC.** UDFs, Triggers, Pipe processors, and AINode 
models execute user-supplied logic/JARs **inside the server process**. 
`USE_UDF`, `USE_TRIGGER`, `USE_PIPE`, and `USE_MODEL` are **grantable system 
privileges** (not strictly root/admin-only). The security-model interpretation 
is that **principals granted these privileges are trusted for the corresponding 
server-side execution capability**; RBAC i [...]
-- **Transport confidentiality/integrity is the operator's job** unless TLS is 
enabled — client Thrift SSL is off by default (`enable_thrift_ssl=false`, §5a), 
so by default IoTDB does not defend against a network attacker 
reading/modifying client traffic. The inter-node channel has **no transport 
encryption today**, and is assumed to run on a trusted network (operators own 
segmentation, §10). *(maintainer — HTHou for the client-SSL default; 
JackieTien97 for the inter-node posture)*
+- **Transport confidentiality/integrity is the operator's job** unless TLS is 
enabled — client Thrift SSL is off by default (`enable_thrift_ssl=false`, §5a), 
so by default IoTDB does not defend against a network attacker 
reading/modifying client traffic. The inter-node and AINode RPC channels have 
**no transport encryption today**, and are assumed to run on a trusted network 
(operators own segmentation, §10). *(maintainer — HTHou for the client-SSL 
default; JackieTien97 for the inter-nod [...]
 - **No defense against a malicious operator / `root`.** *(inferred)*
 - **Default-credential exposure is not IoTDB's bug** — `root:root` is a 
must-change-before-production default, not a supported posture (§5a/§10). 
*(maintainer — HTHou)*
 - **Ordinary resource exhaustion is not a defended property.** Ordinary 
expensive queries or write load that consume CPU/memory/disk are an operator 
capacity/resource-management concern, not an in-model security property — 
unless a specific bug applies (super-linear amplification, a missing limit 
where a limit is expected, or a hang), in which case it is in-model (§8). 
*(maintainer — HTHou)*
@@ -138,7 +156,7 @@ Per-surface trust table *(inferred unless noted; REST/MQTT 
rows apply only when
 
 - Change the default `root` password before any production use or exposure 
outside a trusted environment. *(maintainer — HTHou: must-change before 
production)*
 - Deploy IoTDB inside a trusted network boundary; do **not** expose the client 
RPC port (or an enabled REST/MQTT port) directly to an untrusted/public 
network, especially with default credentials — that is not a supported posture. 
Enable TLS + auth if a wider exposure is unavoidable. *(maintainer — HTHou: 
trusted-network-by-default; public exposure with default creds not supported)*
-- Run the inter-node cluster channel on a trusted/segmented network (or enable 
mutual auth/TLS if supported). *(inferred — pending the §14 inter-node ruling)*
+- Run all core internal endpoints listed in §4 — ConfigNode/DataNode internal 
RPC, MPP data exchange, AINode RPC, and consensus — on a trusted/segmented 
network (or enable mutual auth/TLS if supported). Do not expose these ports to 
an untrusted/public network. *(inferred — consistent with the §14 inter-node 
ruling)*
 - Restrict who is granted the extension system privileges 
(`USE_UDF`/`USE_TRIGGER`/`USE_PIPE`/`USE_MODEL`) — holding one is equivalent to 
server-side code execution; RBAC is the boundary, not a sandbox. *(maintainer — 
HTHou)*
 - Enable client Thrift SSL (`enable_thrift_ssl=true`) where client traffic 
crosses an untrusted segment — it is off by default. *(maintainer — HTHou)*
 - Set filesystem permissions so only the IoTDB user can read the 
data/WAL/config directories. *(inferred)*
@@ -152,6 +170,7 @@ Per-surface trust table *(inferred unless noted; REST/MQTT 
rows apply only when
 - Granting extension system privileges (`USE_UDF`/etc.) to semi-trusted 
clients, treating RBAC as a sandbox rather than an authorization boundary. 
*(maintainer — HTHou)*
 - Building IoTDB SQL by string-concatenating the embedding application's 
untrusted input. *(inferred)*
 - Running a cluster across an untrusted network without inter-node protection. 
*(inferred)*
+- Exposing any core internal port listed in §4 outside the trusted 
cluster/control-plane network. *(inferred)*
 
 ## §11a Known non-findings (recurring false positives)
 
@@ -177,7 +196,7 @@ Per-surface trust table *(inferred unless noted; REST/MQTT 
rows apply only when
 | `VALID` | Violates a §8 property via an in-scope adversary/input (auth 
bypass, cross-path access, pre-auth/malformed-input crash/OOM/hang, privilege 
escalation). | §8, §6, §7 |
 | `VALID-HARDENING` | No §8 property broken, but the API/SQL makes a §11 
misuse easy enough to harden. | §11 |
 | `OUT-OF-MODEL: trusted-input` | Requires an admin/`root` session or 
operator-controlled config/files. | §6, §7 |
-| `OUT-OF-MODEL: adversary-not-in-scope` | Requires a capability the model 
excludes (host control, side channel, direct public exposure, exposed 
inter-node net when posture says trusted). | §3, §7 |
+| `OUT-OF-MODEL: adversary-not-in-scope` | Requires a capability the model 
excludes (host control, side channel, direct public exposure, or direct access 
to a core internal endpoint listed in §4 when posture says trusted). | §3, §4, 
§7 |
 | `OUT-OF-MODEL: unsupported-component` | Lands in `example/`, 
`integration-test/`, or the separate TsFile / SDK repos. | §3 |
 | `OUT-OF-MODEL: non-default-build` | Only manifests under a 
discouraged/non-default §5a setting (e.g. unchanged `root:root`, or an 
explicitly-enabled REST/MQTT used as if default). | §5a |
 | `BY-DESIGN: property-disclaimed` | Concerns a §9-disclaimed property 
(extension code execution within its RBAC grant, no-TLS-by-default, ordinary 
resource exhaustion, malicious operator). | §9 |
@@ -195,7 +214,7 @@ All items below have now been **confirmed by IoTDB PMC 
members across two review
 
 **Wave 2 — trust boundaries & protocols:**
 4. **Default-enabled protocols:** *resolved* — Thrift session is the primary 
surface; REST (`enable_rest_service=false`) and MQTT 
(`enable_mqtt_service=false`) are **disabled by default**. → §2/§5a/§6. 
*(maintainer)*
-5. **Inter-node trust:** *resolved* — the ConfigNode↔DataNode + consensus 
channel is assumed to run on a **trusted network** and currently has **no 
transport encryption**; a finding requiring interception/modification of 
inter-node traffic is `OUT-OF-MODEL: adversary-not-in-scope`, and operators own 
network segmentation (§10). → §4/§7/§9. *(maintainer — JackieTien97)*
+5. **Inter-node/internal RPC trust:** *resolved* — the ConfigNode/DataNode 
internal RPC, DataNode MPP data exchange, ConfigNode/DataNode↔AINode RPC, and 
consensus channels listed in §4 are assumed to run on a **trusted network** and 
currently have **no transport encryption**; a finding requiring direct access 
to, or interception/modification of, these internal channels is `OUT-OF-MODEL: 
adversary-not-in-scope`, and operators own network segmentation (§10). → 
§4/§7/§9. *(maintainer — Jack [...]
 6. **TLS defaults:** *resolved* — client Thrift SSL is **off by default** 
(`enable_thrift_ssl=false`); there is **no inter-node TLS today**. → §5a/§9. 
*(maintainer — HTHou for client SSL; JackieTien97 for inter-node)*
 
 **Wave 3 — extension execution & adversary:**

Reply via email to