apache/iotdb), master / 2.0.x line, against which this draft was written.security@apache.org → private@iotdb.apache.org); findings that fall under §3 or §9 will be closed citing this document.CLAUDE.md)CLAUDE.md)root superuser and whoever controls the deployment, configs, and the host. Trusted for the instance. (inferred)Component-family table (in/out = in/out of this model; all rows inferred unless noted):
| Family | Entry point | Touches outside process | In model? |
|---|---|---|---|
| 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 + 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) |
| Client SDKs | iotdb-client-{go,nodejs,csharp} (separate repos) | — | Out of this batch — deferred to later submissions (per engagement scope) |
example/, integration-test/ | demo + test code | — | Out (see §3) |
example/, integration-test/, build/distribution tooling. Shipped in the repo but not a production trust surface; threat-model separately if ever promoted. (inferred)apache/tsfile; a parsing/decoding finding in TsFile is routed there, not here (this model covers IoTDB's use of TsFile, not the format library). (maintainer — JackieTien97: TsFile findings route to apache/tsfile; the iotdb-client-* SDKs are out of this batch)iotdb-client-go/nodejs/csharp) — out of this scan batch by agreement; each is enrolled separately as its discoverability lands. (documented — engagement scope)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 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 network segmentation (§10). (maintainer — JackieTien97; AINode RPC classification clarified here)
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.properties)
Reachability preconditions per component (the test a triager applies before anything else):
root/admin session is out-of-model: trusted-input unless it crosses into host compromise the operator didn't already have. (inferred)OUT-OF-MODEL: adversary-not-in-scope. (maintainer — JackieTien97)max open files raised to 65535. (documented for the fd limit; filesystem-privacy inferred)Knobs that change which security properties hold:
root:root — IoTDB ships a single fixed administrator root with password root. (documented — Authority-Management docs) This default exists for initial setup and local getting-started use; it is a must-change before production use or exposure outside a trusted environment, and is not a supported production posture. A report that merely observes the default credential is therefore OUT-OF-MODEL: non-default-build (operator must-change), not a code bug in itself. (maintainer — HTHou: “the default administrator account/password exists for initial setup and local getting-started use … must-change before production use or exposure outside a trusted environment, not as a supported production posture”)enable_rest_service=false). In-model only when the operator has explicitly enabled it. (maintainer — HTHou)enable_mqtt_service=false). In-model only when explicitly enabled. (maintainer — HTHou)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)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)USE_UDF/USE_TRIGGER/USE_PIPE/USE_MODEL); see §9. (maintainer — HTHou)Per-surface trust table (inferred unless noted; REST/MQTT rows apply only when the operator has enabled those services — both are off by default per §5a):
| Surface | Input | Attacker-controllable? | Caller/operator must enforce |
|---|---|---|---|
Thrift session openSession / login | username, password | yes (pre-auth) | strong root password; lock-out / rate-limit posture |
| Thrift session execute (SQL / inserts) | SQL text, tablet/row payloads, paths | yes, within granted privileges | privilege grants; query resource limits |
| 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 |
| 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 |
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 here; rest inferred)(Inferred pending PMC confirmation unless tagged — a property only counts once the project commits to it.)
(The highest-value section for integrators — inferred unless tagged, confirm each.)
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 is the authorization boundary here, not a sandbox. A scan reporting “UDF/Trigger/Pipe/Model allows arbitrary code execution” is therefore BY-DESIGN for a principal holding the relevant grant. (maintainer — HTHou: “system privileges and … grantable privileges, not strictly root/admin-only … principals granted these privileges are trusted for the corresponding server-side execution capability. RBAC is the authorization boundary here, not a sandbox.”)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-node posture)root. (inferred)root:root is a must-change-before-production default, not a supported posture (§5a/§10). (maintainer — HTHou)USE_UDF/USE_TRIGGER/USE_PIPE/USE_MODEL is a grant of server-side code execution, not a safe boundary against hostile code. The username/password login is not a defense against a network MITM without TLS (off by default). (maintainer — HTHou: “RBAC is the authorization boundary here, not a sandbox”)(Inferred unless tagged — confirm.)
root password before any production use or exposure outside a trusted environment. (maintainer — HTHou: must-change before production)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_thrift_ssl=true) where client traffic crosses an untrusted segment — it is off by default. (maintainer — HTHou)(Draft one-liners — expand before publishing.)
root:root credentials (non-supported posture, §3). (maintainer — HTHou)USE_UDF/etc.) to semi-trusted clients, treating RBAC as a sandbox rather than an authorization boundary. (maintainer — HTHou)(Inferred unless tagged; the PMC's confirmations here are the highest-leverage suppression input for the scan.)
USE_UDF/USE_TRIGGER/USE_PIPE/USE_MODEL system privileges (§9); the principal holding the grant is trusted for that capability. Not a finding. (maintainer — HTHou)root” — operator must-change-before-production per §5a/§10; OUT-OF-MODEL: non-default-build, not a code bug in itself. (maintainer — HTHou)root can do destructive operation X” — out-of-model: the admin is trusted (§7). (inferred)root:root → forced change), default TLS, or default-enabling of REST/MQTT (both off today). (maintainer for current defaults — HTHou)example/ code into the production trust surface. (inferred)| Disposition | Meaning | Licensed by |
|---|---|---|
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, 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 |
KNOWN-NON-FINDING | Matches a §11a entry. | §11a |
MODEL-GAP | Cannot be cleanly routed — triggers a §12 revision. | §12 |
All items below have now been confirmed by IoTDB PMC members across two review passes — HTHou (issue-comment review, 2026-06-03) and JackieTien97 (PR review, 2026-06-04) — and folded into the body; they are retained here only as a record of the resolution. With both passes in, the core model (§2–§13) is PMC-confirmed; any remaining (inferred) tags are limited to low-stakes environmental details (e.g. filesystem-privacy, thread-safety correctness assumptions).
Wave 1 — scope & intended posture (resolved by HTHou; recorded):
root:root: resolved — must-change before production/exposure, not a supported production posture; report = OUT-OF-MODEL: non-default-build. → §5a/§10/§11a. (maintainer)apache/tsfile; the iotdb-client-* SDKs are out of this batch. → §2/§3. (maintainer — JackieTien97)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/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 — JackieTien97; AINode RPC classification clarified here) 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: 7. Extension privilege model: resolved — USE_UDF/USE_TRIGGER/USE_PIPE/USE_MODEL are grantable system privileges (not strictly root-only); server-side code execution by a principal holding the grant is by-design; RBAC is the boundary, not a sandbox. → §9/§11a/§13. (maintainer) 8. Cluster Byzantine posture: resolved — cluster membership is assumed fully trusted; IoTDB does not claim Byzantine fault tolerance and makes no safety/liveness guarantee against an authenticated-but-malicious peer. → §7/§8. (maintainer — JackieTien97)
Wave 4 — properties & resource line: 9. Resource/DoS line: resolved — malformed/pre-auth/client input causing crash/OOM/deadlock/clearly-unbounded behavior is in-model; ordinary expensive queries or write load are an operator capacity concern unless a specific bug applies (super-linear amplification, missing-expected-limit, or a hang). → §8/§9/§11a. (maintainer) 10. Other recurring false positives: resolved — no additional recurring false positives beyond the §11a seed list at this time. → §11a. (maintainer — JackieTien97) 11. Meta / canonical location: resolved — keep the model in-repo as proposed (AGENTS.md → SECURITY.md → THREAT_MODEL.md); the IoTDB PMC owns revisions. → §1. (maintainer — JackieTien97)