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

git-hulk pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new d90f24823 chore(security): add draft threat model and SECURITY.md for 
security-model discoverability (#3509)
d90f24823 is described below

commit d90f248235b328dea3c0153c90e2f048c55bdd27
Author: Jarek Potiuk <[email protected]>
AuthorDate: Fri Jun 5 04:32:04 2026 +0200

    chore(security): add draft threat model and SECURITY.md for security-model 
discoverability (#3509)
    
    **This is a draft proposal for the Kvrocks PMC to review — please
    correct, reject, or discuss as needed.** Nothing here is a requirement;
    the maintainers are the decision-makers, and this document describes
    Kvrocks *as the PMC says it is*.
    
    This PR adds **`THREAT_MODEL.md`** + **`SECURITY.md`** and a
    **Security** section in `AGENTS.md`, so an automated scan agent can
    mechanically find the model via `AGENTS.md → SECURITY.md →
    THREAT_MODEL.md`.
    
    It is **draft-first and mostly inferred** (~16 documented / 0 maintainer
    / ~50 inferred). Every `*(inferred)*` claim routes to a numbered
    question in **§14 Open questions** — the fastest review is to walk §14
    (three short waves) and answer in-thread; we then promote the tags to
    `*(maintainer)*`.
    
    The **wave-1** rulings are load-bearing:
    
    - Is running **without `requirepass`** (the default) a supported posture
    relying on `bind`/network controls, or must operators set it before
    exposing the port — i.e. is an unauthenticated-access report `BY-DESIGN`
    or `VALID`?
    - Same for **TLS-off** on an untrusted network — operator responsibility
    or a claimed gap?
    - Are **replication / cluster peers** trusted (out of the adversary
    model) or should a malicious peer be in scope?
    
    `apache/kvrocks-controller` is in scope for the scan too; per §14 q10 it
    will get its **own** model (its trust surface — the cluster control
    plane — differs), which we'll open as a separate PR.
    
    Context: the ASF Security team is preparing the project for an automated
    agentic security scan we're piloting; a complete, discoverable threat
    model keeps that scan's output signal-rich. We drafted this via the
    
[threat-model-producer](https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573)
    rubric. If you'd rather author it yourselves, close this PR and we'll
    regroup.
---
 AGENTS.md       |  10 ++
 SECURITY.md     |  17 +++
 THREAT_MODEL.md | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 385 insertions(+)

diff --git a/AGENTS.md b/AGENTS.md
index a5b6784ff..79a13e9eb 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -174,3 +174,13 @@ Common scopes: `server`, `storage`, `commands`, `cluster`, 
`search`, `types`, `r
 - Prefer focused patches over broad refactors when contributing.
 - Some website or documentation tasks may belong in the separate website 
repository rather than this repository.
 - If AI assistance is used, keep the generated changes reviewable and be able 
to explain and defend the final patch.
+
+## Security
+
+Security model: [SECURITY.md](./SECURITY.md) → 
[THREAT_MODEL.md](./THREAT_MODEL.md)
+
+Agents that scan this repository should consult `SECURITY.md` and the linked
+`THREAT_MODEL.md` for the project's threat model — in-scope / out-of-scope
+declarations, the security properties claimed and disclaimed (namespace
+isolation, admin/namespace token separation, the Lua sandbox), the adversary
+model, and known non-findings — before reporting issues.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..859908204
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,17 @@
+# Security Policy
+
+## Reporting a Vulnerability
+
+Apache Kvrocks follows the [Apache Software Foundation security 
process](https://www.apache.org/security/).
+Please report suspected vulnerabilities **privately** to `[email protected]` 
(the Kvrocks PMC is reachable
+at `[email protected]`). Do **not** open public GitHub issues or pull 
requests for security reports.
+
+When reporting, include the affected version, a description, and — if you can 
— which security property you
+believe is violated (see the Threat Model below) and a reproduction.
+
+## Threat Model
+
+What Kvrocks considers in scope and out of scope, the security properties it 
claims and the ones it explicitly
+disclaims (namespace isolation, admin/namespace token separation, the Lua 
sandbox, the no-auth/no-TLS defaults),
+the adversary model, and how inbound reports and tool/AI findings are triaged 
are documented in
+[THREAT_MODEL.md](./THREAT_MODEL.md). Reporters and triagers should consult it 
alongside this policy.
diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md
new file mode 100644
index 000000000..8b3b846bb
--- /dev/null
+++ b/THREAT_MODEL.md
@@ -0,0 +1,358 @@
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+Licensed 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
+
+    https://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.
+-->
+
+# Threat Model — Apache Kvrocks
+
+## §1 Header
+
+- **Project:** Apache Kvrocks — a distributed key-value NoSQL database that 
uses RocksDB as its
+  storage engine and is compatible with the Redis (RESP) protocol, adding 
namespace-token
+  multi-tenancy, binlog-based async replication, Redis-Sentinel failover, and 
a proxyless
+  centralized cluster mode *(documented — README)*.
+- **Modelled against:** `apache/kvrocks` `unstable`/HEAD (2026-05-31).
+- **Status:** **DRAFT — v0, reviewed by the Kvrocks PMC (PragmaTwice).** 
Produced by the ASF Security team
+  via the `threat-model-producer` rubric
+  (<https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573>) for the 
PMC to react to. PragmaTwice
+  (Kvrocks PMC) has reviewed and answered the open questions; all §14 items 
are resolved and folded in as
+  *(maintainer)*.
+- **Version binding:** versioned with the project; a report against release 
*N* is triaged against the
+  model as it stood at *N*.
+- **Reporting cross-reference:** §8-property violations → report privately per 
`SECURITY.md` /
+  <https://www.apache.org/security/>; §3 / §9 findings are closed citing this 
document.
+- **Provenance legend:** *(documented)* = Kvrocks 
docs/README/`kvrocks.conf`/source; *(maintainer)* =
+  confirmed by a Kvrocks PMC member; *(inferred)* = reasoned from 
code/config/Redis-family domain
+  norms, **not yet confirmed** — each routes to a §14 question.
+- **Draft confidence:** with PragmaTwice's review folded in, the core model 
(§2–§13) is PMC-confirmed; the residual *(inferred)* tags are limited to 
low-stakes environmental details (host-inventory, platform specifics).
+
+Kvrocks is a network server: clients speak the Redis wire protocol to it over 
TCP (default port
+`6666`, default `bind 127.0.0.1`) *(documented — `kvrocks.conf`)*. Data is 
partitioned into
+**namespaces**, each gated by its own token; the `requirepass` value is the 
**admin token** and is the
+only one permitted to run namespace-management and sensitive admin commands 
such as `config`,
+`slaveof`, and `bgsave` *(documented — README, Namespace section)*. 
Persistence is RocksDB on local
+disk; replication ships a binlog from master to replica.
+
+## §2 Scope and intended use
+
+Primary intended use *(documented)*: a self-hosted, Redis-compatible KV store 
optimized for larger-than-
+memory datasets on RocksDB, accessed by Redis clients, optionally clustered.
+
+Caller roles:
+
+- **Unauthenticated client** — a TCP peer that has not presented a valid 
token; untrusted.
+- **Namespace client** — authenticated with a namespace token; trusted only 
within its namespace.
+- **Admin client** — authenticated with the `requirepass` admin token; trusted 
for the instance.
+- **Replica / cluster peer** — another Kvrocks node in the same 
replication/cluster topology; assumed
+  operator-provisioned and trusted *(maintainer — peers are trusted)*.
+- **Operator / deployer** — controls `kvrocks.conf`, the data directory, TLS 
material, and the network
+  exposure. Fully trusted; **out of model** as adversary (§3).
+
+**Component-family table:**
+
+| Family | Entry point | Touches outside process | In model? |
+| --- | --- | --- | --- |
+| RESP command + connection layer | TCP `:6666`, `src/server`, command 
dispatch | network | **Yes** |
+| AuthN + namespace isolation | `AUTH`, namespace tokens, `requirepass` | — | 
**Yes** |
+| Admin command surface | `config`, `slaveof`, `bgsave`, `namespace`, 
`cluster`, `debug` | disk / net | **Yes** |
+| Lua scripting | `EVAL`/`FUNCTION`, `src/commands/cmd_script.cc`, 
`src/storage/scripting.cc` (LuaJIT) | sandboxed Lua | **Yes** |
+| Storage engine | RocksDB, `src/storage` | filesystem | **Yes** |
+| Replication | binlog master→replica (async) | network | **Yes** |
+| Cluster mode | proxyless centralized cluster, slot migration | network | 
**Yes** |
+| TLS transport (optional) | `tls-*` config | network | **Yes** (when enabled) 
|
+| Build / dev tooling | `dev/`, `utils/`, `x.py`, `cmake/` | — | No → §3 |
+| Tests | `tests/` | — | No → §3 |
+
+## §3 Out of scope (explicit non-goals)
+
+- **The operator / deployer as adversary.** Anyone who can edit 
`kvrocks.conf`, read the RocksDB data
+  directory, hold the admin token, or change the bind/TLS posture has already 
won (§9) *(inferred)*.
+- **Network/transport hardening beyond what Kvrocks offers.** When TLS is 
disabled (default), confidentiality
+  and integrity of the wire — including the auth token — are the deployment's 
responsibility (firewalling,
+  private network, or enabling TLS) *(documented — TLS is opt-in in 
`kvrocks.conf`)*.
+- **A downstream proxy/app that builds RESP commands from untrusted user 
input.** Command-injection at that
+  layer is the integrator's problem, not Kvrocks's (§9).
+- **Custom builds** with non-default compile options, and operator-supplied 
Lua scripts run under the admin
+  token.
+- **Shipped-but-unsupported code:** `dev/`, `utils/`, `x.py`, `tests/` 
*(inferred)*.
+
+## §4 Trust boundaries and data flow
+
+The trust boundary is the **TCP connection + the token presented on it**. A 
connection's identity
+(unauthenticated → namespace → admin) determines which commands and which 
keyspace it may touch
+*(documented — namespace/admin-token rules)*.
+
+Trust transitions:
+
+1. **Connect → AUTH:** a new connection is unauthenticated. If `requirepass` 
(or namespace tokens) are
+   configured, commands are refused until a valid token is presented via 
`AUTH` *(maintainer —
+   PragmaTwice: commands are refused pre-`AUTH` when a token is configured; 
default `requirepass` is unset, see §5a)*.
+2. **Namespace token → keyspace:** a namespace-authenticated connection is 
confined to that namespace's
+   keys and is denied admin/namespace/cluster commands *(maintainer — strict 
per-namespace keyspace
+   confinement; admin-only metadata)*.
+3. **Admin token → full control:** the admin token may run all commands, 
including `config`, `slaveof`,
+   `bgsave`, namespace management, and cluster operations *(documented)*.
+4. **EVAL → Lua sandbox:** scripts execute in the embedded LuaJIT sandbox, 
which is intended to deny
+   arbitrary host access *(maintainer — scripting confined to the namespace; 
no host access)*.
+5. **Master → replica:** the master streams a binlog to replicas; the replica 
applies it. Peers are
+   mutually trusted within the topology *(maintainer — peers are trusted)*.
+
+**Reachability preconditions:**
+
+- A finding in the **command/RESP** path is in-model if reachable from an 
unauthenticated or
+  namespace-token connection (admin-token-only reach → lower severity, see §7).
+- A finding in **namespace isolation** is in-model if it lets a namespace 
token read/write outside its
+  namespace or run an admin-only command.
+- A finding in **Lua scripting** is in-model if a script permitted to a 
non-admin caller can break the
+  sandbox or access another namespace / host resources.
+- A finding reachable only from `kvrocks.conf`, the data dir, or the admin 
token is out of model (§3).
+- A finding requiring a malicious replica/cluster peer is **out of model** — 
peers are trusted
+  *(maintainer)*.
+
+## §5 Assumptions about the environment
+
+- **OS/runtime:** a POSIX host with a filesystem for the RocksDB data 
directory; a conformant C++ runtime
+  *(inferred)*.
+- **Network:** the operator controls who can reach the listening port; default 
`bind 127.0.0.1` limits this
+  to localhost until changed *(documented — `kvrocks.conf`)*.
+- **Storage:** local disk is trusted; RocksDB data at rest is **not** 
encrypted by Kvrocks, and no
+  per-namespace encryption is claimed *(maintainer — no per-namespace 
encryption claimed)*.
+- **Replication/cluster peers:** provisioned by the operator on a trusted 
network; peers are trusted
+  *(maintainer)*.
+- **What Kvrocks does to its host (inventory, *(inferred)* — wave-2 target):** 
binds a TCP port; reads/writes
+  the configured data directory; reads `kvrocks.conf`; opens outbound 
connections to replication masters /
+  cluster peers; may write RDB/backup files on `bgsave`. Not assumed to spawn 
shells or read arbitrary files
+  outside its data dir (Lua sandbox permitting).
+
+## §5a Build-time and configuration variants
+
+These `kvrocks.conf` knobs change which §8 properties hold. **Defaults below 
are documented; the
+maintainer has clarified the supported posture for the auth/TLS defaults (see 
rulings).**
+
+| Knob | Default *(documented — `kvrocks.conf`)* | Effect | Insecure-default 
ruling |
+| --- | --- | --- | --- |
+| `requirepass` | **unset (commented)** | No admin token ⇒ **no 
authentication**; all clients are effectively admin | *(maintainer)* If 
`requirepass` is unset, operators are responsible for restricting access to 
trusted personnel only; an unauth-access report against a routable, 
no-`requirepass` deployment is operator responsibility |
+| `bind` | `127.0.0.1` | Localhost-only by default; limits exposure | Safe 
default; reports requiring a routable bind + no auth are operator misconfig |
+| `tls-port` / `tls-*` | **off** | No transport encryption ⇒ token + data in 
plaintext on the wire | *(maintainer)* Same as `requirepass`: when TLS is off, 
operators are responsible for restricting access to trusted personnel only; 
plaintext-on-untrusted-network is operator responsibility |
+| namespace tokens | none until configured | Multi-tenant isolation only 
exists once namespaces+tokens are set | Strict per-namespace keyspace 
confinement *(maintainer)*; pub/sub is a known exception (§9) |
+| Lua scripting (`EVAL`) | enabled *(inferred)* | Adds a sandboxed 
code-execution surface | Sandbox confined to the namespace; no host access 
*(maintainer)* |
+| `maxclients` / value-size / proto limits | defaults *(inferred)* | DoS 
envelope | No intrinsic guarantee beyond configured limits *(maintainer)* |
+
+## §6 Assumptions about inputs
+
+| Entry point | Parameter | Attacker-controllable? | Caller/operator must 
enforce |
+| --- | --- | --- | --- |
+| any RESP command | command name + arguments | **yes** (any connected client) 
| auth gate; namespace confinement; arg bounds |
+| `AUTH` | token | **yes** | constant-time compare *(maintainer — desirable 
hardening)*; throttling |
+| key/value ops | key, value bytes | **yes** (within namespace) | value-size / 
memory limits |
+| `EVAL`/`FUNCTION` | Lua script body + keys/args | **yes** (if non-admin may 
script) | sandbox; no cross-namespace/host access |
+| `namespace`/`config`/`slaveof`/`bgsave`/`cluster` | args | **yes**, but 
**admin-token-gated** | admin-token-only enforcement |
+| replication stream | binlog bytes from master | from a **trusted** peer 
*(maintainer — peers are trusted)* | peer authenticity (network/TLS) |
+| `kvrocks.conf` | all keys | **no — operator-trusted** | never sourced from a 
client |
+
+Inputs are bounded only where the operator configures limits; Kvrocks provides 
no intrinsic guarantee
+beyond configured limits — it is not assumed to bound pipeline depth, value 
size, `KEYS`/scan cost, or
+Lua run-time intrinsically beyond configured maxima *(maintainer — no 
intrinsic DoS guarantee; §8.6/§9)*.
+
+## §7 Adversary model
+
+- **Primary adversary:** an untrusted TCP client — unauthenticated, or holding 
only a namespace token and
+  trying to exceed it. Capabilities: send arbitrary RESP commands, attempt 
`AUTH`, run permitted Lua, push
+  large/expensive workloads.
+- **Goals:** access data in another namespace or without a token; run admin 
commands without the admin token;
+  break the Lua sandbox; exhaust CPU/memory/disk; read tokens/data off an 
unencrypted wire.
+- **Out of model:** the operator, the admin-token holder, anyone with 
filesystem/`kvrocks.conf` access, and
+  a malicious replication/cluster peer (peers are trusted *(maintainer)*). A 
command reachable **only** with
+  the admin token is `OUT-OF-MODEL: adversary-not-in-scope` unless it crosses 
into the host beyond the
+  documented admin surface.
+
+## §8 Security properties the project provides
+
+*(All *(inferred)* working hypotheses for v0 unless tagged; symptom + severity 
per the rubric.)*
+
+1. **Namespace data isolation.** A connection authenticated with a namespace 
token can access only that
+   namespace's keyspace; it cannot read/write other namespaces *(maintainer — 
strict per-namespace keyspace
+   confinement; admin-only metadata)*. **Known limitation:** pub/sub does 
**not** currently respect
+   namespaces *(maintainer)* — see §9. *Symptom:* cross-namespace read/write 
(excluding the documented
+   pub/sub limitation). *Severity:* critical.
+2. **Admin/namespace privilege separation.** Only the admin (`requirepass`) 
token may run namespace
+   management and sensitive admin commands (`config`, `slaveof`, `bgsave`, 
cluster ops) *(documented)*.
+   *Symptom:* a namespace/unauth client runs an admin command. *Severity:* 
critical.
+3. **Authentication gate (when configured).** With `requirepass`/namespace 
tokens set, commands beyond
+   `AUTH` are refused on an unauthenticated connection *(maintainer — 
PragmaTwice)*. *Symptom:* pre-auth data access.
+   *Severity:* critical.
+4. **Lua sandboxing.** Scripts run in a constrained LuaJIT environment without 
arbitrary host/file access and
+   confined to the caller's namespace *(maintainer — scripting confined to the 
namespace; no host access)*.
+   *Symptom:* sandbox escape / host access / cross-namespace access from a 
script. *Severity:* critical.
+5. **Memory safety on protocol parsing.** Well-formed and malformed RESP input 
does not cause memory-corruption
+   on supported platforms *(inferred)*. *Symptom:* OOB read/write, crash from 
crafted input. *Severity:*
+   critical.
+6. **Resource bounds.** There is **no intrinsic DoS guarantee beyond 
configured limits** *(maintainer)*;
+   the operator's contract is to configure `maxclients` and size limits. (The 
`luajit_bytecode_dos` test
+   shows Lua DoS is taken seriously, but no broader intrinsic guarantee is 
claimed.) *Symptom:* hang/OOM/disk-fill
+   beyond configured limits. *Severity:* medium (treated as operator-tuning, 
not a property breach, unless a
+   configured limit is bypassed).
+
+## §9 Security properties the project does NOT provide
+
+- **No authentication by default.** `requirepass` ships unset; an operator who 
binds to a routable interface
+  without setting it exposes an **unauthenticated admin-level** store 
*(documented — `kvrocks.conf`)*. The
+  `bind 127.0.0.1` default mitigates this until changed. **When `requirepass` 
is unset, operators are
+  responsible for restricting access to trusted personnel only** 
*(maintainer)*.
+- **No transport encryption by default.** TLS is opt-in; on an untrusted 
network the auth token and all data
+  are observable/modifiable *(documented)*. **As with `requirepass`, when TLS 
is off operators are responsible
+  for restricting access to trusted personnel only** *(maintainer)*.
+- **No defence against the operator / admin-token holder** (§3).
+- **Namespace isolation is logical, not cryptographic.** All namespaces share 
one RocksDB instance on disk;
+  isolation is an access-control property at the command layer, not at-rest 
encryption or per-tenant key
+  separation. **No per-namespace encryption is claimed** *(maintainer)*.
+- **Pub/sub does not respect namespaces (known limitation).** Namespace 
keyspace confinement is strict for
+  keys, but pub/sub channels are **not** currently namespaced — a namespace 
client can publish/subscribe
+  across the instance *(maintainer — known limitation)*. This is a documented 
current limitation rather than
+  a property breach; a report matching exactly this behaviour is a 
`KNOWN-NON-FINDING` (§11a), while
+  namespacing pub/sub is desirable hardening.
+- **No strong anti-DoS guarantee** against expensive commands (`KEYS`, large 
`MGET`, huge values, deep
+  pipelines) or adversarial Lua beyond configured limits — **no intrinsic 
guarantee beyond configured limits**
+  *(maintainer)*.
+
+**False-friend properties:**
+
+- *The namespace token looks like a per-user credential but is a shared 
per-namespace secret* — anyone with
+  the token is every user of that namespace; rotation is manual (`namespace 
set`).
+- *`requirepass` looks like "a password" but is the **admin** token* — it is 
not a low-privilege credential;
+  giving it out grants full control.
+- *Namespace confinement looks total but pub/sub is an exception* — keyspace 
access is strictly confined, but
+  pub/sub channels currently cross namespaces *(maintainer)*.
+- *Replication/cluster membership is authenticated and peers are trusted* — it 
is **not** a defence against a
+  malicious peer; the model assumes trusted peers *(maintainer)*.
+
+**Well-known attack classes left to the operator/integrator:**
+
+- **Unauthenticated exposure** (the Redis-family classic) — set `requirepass` 
and/or restrict `bind`; when
+  unset, restrict access to trusted personnel *(maintainer)*.
+- **Plaintext token/data sniffing & MITM** without TLS — when TLS is off, 
restrict access to trusted personnel
+  *(maintainer)*.
+- **RESP command injection** from a downstream app that interpolates untrusted 
input into commands.
+- **Lua-based DoS / sandbox probing.**
+- **Cross-namespace pub/sub** on a multi-tenant instance (known limitation, 
§9).
+
+## §10 Downstream (operator) responsibilities
+
+- **Set `requirepass` (and namespace tokens) before binding to any 
non-localhost interface; if `requirepass`
+  is left unset, restrict access to trusted personnel only** *(maintainer)*.
+- Enable TLS (`tls-port`, certs, `tls-auth-clients`) on untrusted networks; 
otherwise keep traffic on a
+  trusted/segmented network. **When TLS is off, restrict access to trusted 
personnel only** *(maintainer)*.
+- Treat the admin token as root-equivalent; distribute only namespace tokens 
to tenants; rotate on exposure.
+- Do not rely on namespace isolation for **pub/sub** — channels are not 
currently namespaced *(maintainer)*.
+- Run replication/cluster peers on a trusted network (and/or with TLS); peers 
are trusted, so provision them
+  yourself *(maintainer)*.
+- Configure resource limits (`maxclients`, value/proto size) for the 
deployment's risk profile — there is no
+  intrinsic DoS guarantee beyond these *(maintainer)*.
+- Protect the RocksDB data directory and backup/RDB files at the filesystem 
layer.
+
+## §11 Known misuse patterns
+
+- Exposing Kvrocks to a routable network with `requirepass` unset 
(unauthenticated admin store) without
+  restricting access to trusted personnel.
+- Handing the admin token to applications that only need a single namespace.
+- Building RESP commands by string-concatenating untrusted user input in a 
downstream app.
+- Running over plaintext on an untrusted network and treating namespace tokens 
as if confidential.
+- Assuming RocksDB-at-rest is per-namespace isolated/encrypted.
+- Relying on namespace isolation for **pub/sub** channels (not currently 
namespaced).
+
+## §11a Known non-findings (recurring false positives)
+
+*(v0 seed — the PMC's real list is the highest-leverage §14 input.)*
+
+- **"No password set"/"unauthenticated access"** flagged against a default 
config — by design, mitigated by
+  `bind 127.0.0.1`; operator responsibility (when `requirepass` is unset, 
operators restrict access to
+  trusted personnel) *(maintainer)* → `BY-DESIGN: property-disclaimed` / 
operator responsibility.
+- **"Plaintext protocol / no TLS"** against default config — TLS is opt-in 
(§9/§10); operator responsibility
+  (restrict access to trusted personnel when TLS is off) *(maintainer)*.
+- **Cross-namespace pub/sub** — pub/sub does not currently respect namespaces; 
this is a known limitation, not
+  a property breach *(maintainer)* → `KNOWN-NON-FINDING` (namespacing pub/sub 
is desirable hardening).
+- **Admin command "danger" (`FLUSHALL`, `CONFIG`, `DEBUG`, `bgsave`)** 
reachable with the admin token — by
+  design; admin token is root-equivalent (§7).
+- **Findings in `tests/`, `dev/`, `utils/`, `x.py`** — out of scope (§3).
+- **RESP command injection** attributable to a downstream caller concatenating 
input — not a Kvrocks bug (§9).
+- **RocksDB-internal warnings** from the bundled storage engine that are not 
reachable from client input.
+- **Non-constant-time token compare** in `AUTH` — constant-time compare is 
desirable hardening, not a property
+  breach *(maintainer)* → `VALID-HARDENING`.
+
+## §12 Conditions that would change this model
+
+- A new command that crosses the namespace boundary or relaxes admin-token 
gating.
+- A change to the default `requirepass`/`bind`/TLS posture.
+- A new client-reachable surface (new protocol, HTTP admin API, new cluster 
control plane).
+- A change to the Lua sandbox scope or who may script.
+- Treating replication/cluster peers as untrusted (would pull them into §7).
+- Namespacing pub/sub (would close the known limitation in §9).
+- Any report that can't be routed to a single §13 disposition (→ revise the 
model).
+
+## §13 Triage dispositions
+
+| Disposition | Meaning | Licensed by |
+| --- | --- | --- |
+| `VALID` | Violates a claimed property via an in-scope adversary/input. | §8, 
§6, §7 |
+| `VALID-HARDENING` | No §8 property broken, but a §11 misuse is easy enough 
to warrant hardening (e.g. constant-time `AUTH` compare, namespacing pub/sub). 
| §11 |
+| `OUT-OF-MODEL: trusted-input` | Requires control of a trusted input (config 
/ admin token / replica stream). | §6 |
+| `OUT-OF-MODEL: adversary-not-in-scope` | Requires operator / admin-token / 
filesystem / trusted-peer capability. | §7, §3 |
+| `OUT-OF-MODEL: unsupported-component` | Lands in `tests/`, `dev/`, `utils/`, 
tooling. | §3 |
+| `OUT-OF-MODEL: non-default-build` | Only under a discouraged/non-default 
`kvrocks.conf` setting. | §5a |
+| `BY-DESIGN: property-disclaimed` | Concerns a §9-disclaimed property 
(no-auth default, no-TLS default, logical-only namespace isolation, 
non-namespaced pub/sub). | §9 |
+| `KNOWN-NON-FINDING` | Matches a §11a entry (incl. cross-namespace pub/sub). 
| §11a |
+| `MODEL-GAP` | Routes to none of the above → revise the model. | §12 |
+
+## §14 Open questions for the maintainers
+
+All questions below have been answered by PragmaTwice (Kvrocks PMC) and folded 
into the body as
+*(maintainer)*; they are retained as a record of the resolution. Three waves.
+
+**Wave 1 — scope & insecure-default rulings (§2/§3/§5a/§8/§9):**
+1. *(Answered — maintainer.)* Running **without `requirepass`** / with **TLS 
off**: operators are responsible
+   for restricting access to trusted personnel only. An unauth/plaintext 
report against such a deployment is
+   operator responsibility, not a property breach. *Remaining:* none.
+2. *(Answered — maintainer.)* **Replication / cluster peers are trusted** — a 
malicious peer holding valid
+   topology credentials is out of the §7 adversary model. *Remaining:* none.
+3. *(Answered — maintainer.)* The **authentication gate** (§8.3) behaves as 
expected: commands are refused
+   pre-`AUTH` on an unauthenticated connection once a token is configured. 
*Remaining:* none.
+
+**Wave 2 — isolation & scripting (§4/§8):**
+4. *(Answered — maintainer.)* **Namespace isolation:** strict per-namespace 
keyspace confinement; metadata is
+   admin-only. **Known limitation:** pub/sub does **not** currently respect 
namespaces (documented in §9 as a
+   known limitation / `KNOWN-NON-FINDING`; namespacing it is desirable 
hardening). *Remaining:* none — strict
+   per-namespace keyspace confinement holds; pub/sub is the only documented 
cross-namespace exception.
+5. *(Answered — maintainer.)* **Lua scripting** is confined to the caller's 
namespace with no host access;
+   namespace clients may run it, confined to their namespace. *Remaining:* 
none.
+6. *(Answered — maintainer.)* **RocksDB data-at-rest** is operator-trusted 
disk; **no per-namespace encryption
+   is claimed**. *Remaining:* none.
+
+**Wave 3 — resource line, auth hardening, §11a (§8/§9/§11a):**
+7. *(Answered — maintainer.)* **Resource line:** no intrinsic guarantee beyond 
configured limits; the contract
+   is to configure `maxclients` and size limits. *Remaining:* none.
+8. *(Answered — maintainer.)* **`AUTH` hardening:** network controls are 
expected; a constant-time token
+   compare is **desirable hardening** (`VALID-HARDENING`), not a property 
breach; brute-force throttling is
+   operator/network responsibility. *Remaining:* none.
+9. *(Answered — maintainer.)* The §11a list above is the PMC's 
recurring-non-finding set; no additions at
+   this time.
+
+**Meta:**
+10. *(Answered — maintainer.)* This model lives in root `THREAT_MODEL.md` 
referenced from `SECURITY.md` (this
+    PR) and covers `apache/kvrocks`; `apache/kvrocks-controller` has its own 
model (its cluster-control-plane
+    trust surface differs).
+
+## §15 Machine-readable companion
+
+Deferred for v0. A `threat-model.yaml` can later encode the §6 trust table, 
§2/§3 component scoping, §8
+property/severity/symptom rows, §9 false friends, §11a non-findings, and §13 
dispositions for automated triage.

Reply via email to