apache/kvrocks unstable/HEAD (2026-05-31).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).SECURITY.md / https://www.apache.org/security/; §3 / §9 findings are closed citing this document.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.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.
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:
requirepass admin token; trusted for the instance.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 |
kvrocks.conf, read the RocksDB data directory, hold the admin token, or change the bind/TLS posture has already won (§9) (inferred).kvrocks.conf).dev/, utils/, x.py, tests/ (inferred).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:
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).config, slaveof, bgsave, namespace management, and cluster operations (documented).Reachability preconditions:
kvrocks.conf, the data dir, or the admin token is out of model (§3).bind 127.0.0.1 limits this to localhost until changed (documented — kvrocks.conf).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).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) |
| 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).
AUTH, run permitted Lua, push large/expensive workloads.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.(All (inferred) working hypotheses for v0 unless tagged; symptom + severity per the rubric.)
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.requirepass/namespace tokens set, commands beyond AUTH are refused on an unauthenticated connection (maintainer — PragmaTwice). Symptom: pre-auth data access. Severity: critical.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).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).requirepass, when TLS is off operators are responsible for restricting access to trusted personnel only (maintainer).KNOWN-NON-FINDING (§11a), while namespacing pub/sub is desirable hardening.KEYS, large MGET, huge values, deep pipelines) or adversarial Lua beyond configured limits — no intrinsic guarantee beyond configured limits (maintainer).False-friend properties:
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.Well-known attack classes left to the operator/integrator:
requirepass and/or restrict bind; when unset, restrict access to trusted personnel (maintainer).requirepass (and namespace tokens) before binding to any non-localhost interface; if requirepass is left unset, restrict access to trusted personnel only (maintainer).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).maxclients, value/proto size) for the deployment's risk profile — there is no intrinsic DoS guarantee beyond these (maintainer).requirepass unset (unauthenticated admin store) without restricting access to trusted personnel.(v0 seed — the PMC's real list is the highest-leverage §14 input.)
bind 127.0.0.1; operator responsibility (when requirepass is unset, operators restrict access to trusted personnel) (maintainer) → BY-DESIGN: property-disclaimed / operator responsibility.KNOWN-NON-FINDING (namespacing pub/sub is desirable hardening).FLUSHALL, CONFIG, DEBUG, bgsave) reachable with the admin token — by design; admin token is root-equivalent (§7).tests/, dev/, utils/, x.py — out of scope (§3).AUTH — constant-time compare is desirable hardening, not a property breach (maintainer) → VALID-HARDENING.requirepass/bind/TLS posture.| 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 |
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):
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.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).
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.