Security · 2026-05-17 · By RedDB team · 12 min read

Threat model: what RedDB protects against (and what it doesn't)

An honest STRIDE walkthrough of the RedDB engine and vault. What the database protects against (cold-storage breach, replicated-secret leakage, key compromise during rotation) and what it does not (compromised application process, host-level side channels, malicious operator). Gaps are named, not hidden.

Most database security marketing reads like the result is the same regardless of the question: encrypted at rest, encrypted in transit, role-based access control, audit logs. Tick, tick, tick, tick. That tells you nothing about which attacks fail and which ones succeed against the system you are about to put production data into.

This post is the opposite shape. It walks the RedDB engine and the vault through STRIDE, names the attacker for each category, and at each step says one of two things: we stop this or we do not stop this — here is what does. The “do not” list is the important half. If your threat model includes one of those attackers, RedDB on its own is not your answer and you should know that before signing the contract, not after.

We have had this conversation with security leads at every regulated-industry buyer we have talked to. The shape of the conversation is always the same: they want to know where the boundary is. So here is the boundary, written down.

The boundary, stated once

RedDB defends the data at rest and the bytes on the wire between replicas. Anything that happens inside a process holding a valid in-memory key — including the RedDB process itself — is outside the boundary. That is not a hedge; it is the design.

Three concrete consequences fall out of that one sentence:

  1. A stolen disk, snapshot, or backup is useless without the master key. Cold-storage breach is the attack we put the most engineering into stopping.
  2. A compromised application process that holds a live decryption key is game over for the rows that key opens. No database-level control fixes this. The fix lives in your process isolation, secrets handling, and BYOK story.
  3. A malicious operator with shell on a running RedDB node can read decrypted hot data. Defence here is operational (least privilege, BYOK with customer-held KMS, audit on the KMS side) — not cryptographic.

Hold those three in your head; the STRIDE walk below is just the long form.

STRIDE, one row at a time

STRIDE is the six-category threat taxonomy from Microsoft: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege. It is not the only frame, but it is the one most security leads have already read, so it is the one we use when they ask.

For each category we name the attacker, what they can do, and whether the engine stops them.

S — Spoofing

Attacker: a network peer impersonating a legitimate RedDB node or client.

What we stop:

  • Replica-to-replica spoofing. Replicas authenticate to each other with mTLS using a cluster-issued certificate authority. A peer without a cert signed by that CA cannot join the gossip ring, cannot receive replication traffic, and cannot serve reads.
  • Client-to-cluster spoofing. Client connections are mTLS by default in production profile. The control plane issues short-lived client certs scoped to a tenant; a stolen long-lived API token alone is not sufficient if the operator has enabled the production profile (it is the default; turning it off is a deliberate config change that is logged).

What we do not stop:

  • A compromised CA. If your private CA is exfiltrated, the attacker can mint valid certs and the engine cannot tell them from a real client. Defence is CA isolation (HSM-backed, ideally) and short cert lifetimes so a leak has a bounded blast radius. This is a property of every mTLS system; we do not pretend to fix it.
  • In-process impersonation. If a compromised application process has access to your client certificate and key, it is a legitimate client from the engine’s perspective. See “I — Information disclosure” below.

T — Tampering

Attacker: someone modifying data at rest, in transit, or in a backup.

What we stop:

  • Wire tampering between replicas. mTLS provides integrity in transit; a flipped bit on the wire fails the TLS MAC and the connection drops.
  • At-rest tampering of encrypted rows. Each per-row envelope (g, iv, ciphertext) uses an AEAD (AES-GCM by default). A modified ciphertext fails authentication on decrypt and the read returns an error rather than corrupt plaintext. This holds whether the modification happened in the SSTable file, in a backup, or in a snapshot copy.
  • At-rest tampering of unencrypted columns. SSTables carry block-level checksums (xxh3) that are verified on read. A bit-flip in a non-vault column surfaces as a read error, not silently corrupt output.

What we do not stop:

  • A privileged operator with write access to the disk path. Truncating an SSTable, deleting a WAL segment, or rolling back a snapshot is indistinguishable from legitimate ops at the cryptographic layer. Defence is file-system permissions and an immutable backup destination (object-lock S3, or equivalent). The engine assumes its own disk is trusted.
  • A compromised application that issues legitimate writes. If the attacker can call PUT, the writes are authentic from the engine’s perspective. This is intentional — the engine is not in the business of policing application-level semantics.

R — Repudiation

Attacker: someone who wants to deny they did a thing.

What we stop:

  • Write attribution. Every mutation carries the client identity (subject DN from the mTLS cert) into a transactional audit log. The audit log is written in the same transaction as the data and is one of the streams the hooks layer emits; if the write commits, the audit row commits.
  • Audit log tampering. Audit rows are vault-encrypted with a generation-pinned key separate from the application key, so an operator who can rotate the application key cannot quietly rewrite history.

What we do not stop:

  • An attacker who has the legitimate client cert. The audit log will faithfully attribute their writes to whoever owns that cert. Repudiation defence at this layer is identity hygiene, not cryptography.
  • Backdated entries written by a compromised RedDB process. The audit log is not externally notarised. If you need stronger non-repudiation (regulator-grade), stream the audit log to an append-only external system (S3 with object lock, a managed audit service) and treat the engine’s copy as a cache. We have customers doing this; it is wired through the same hooks API.

I — Information disclosure

This is the category most buyers care about and the one with the most nuance. We split it by where the data lives.

I.1 — Data at rest, on RedDB’s own disks

Attacker: someone who walks off with the disk, the snapshot, or the backup.

What we stop:

  • Every row in a vault-protected column is AES-GCM encrypted with a DEK wrapped by the current master key generation. The disk on its own is ciphertext.
  • WAL segments containing those rows are encrypted with the same envelope before fsync. A leaked WAL does not leak plaintext.
  • Backups are written through the same vault path. Restoring a backup requires access to the master key generations that were active when the backup was taken; the backup file on its own is useless.

What we do not stop:

  • Unencrypted columns. The vault is opt-in per column. If a column is not in the vault config, its plaintext is on disk. This is a deliberate trade — full-database encryption defeats most engine-level features (sort, hybrid search, filters that read the column). Pick what to encrypt; we will not pick for you.
  • An attacker who steals the disk and the live master key. If your KMS credential file is on the same machine as your data files, theft of the machine is theft of both. See BYOK and external KMS.

I.2 — Data in transit

Attacker: a network observer between replicas or between client and cluster.

What we stop:

  • mTLS, modern cipher suites, no TLS 1.0/1.1, no static-key Diffie-Hellman. Wire is opaque.
  • Replication includes ciphertext from the vault path, not plaintext re-encrypted at the link. A passive network observer on the replication link sees the same opaque bytes the disk holds.

What we do not stop:

  • A man-in-the-middle who has a valid cert. Same caveat as Spoofing.
  • Side-channel disclosure via traffic shape. An observer who sees the size and timing of replication packets can learn something about write rate per tenant. This is true of every replicated database and is not part of our threat model.

I.3 — Data in memory, in the RedDB process

Attacker: someone with shell on a running RedDB node.

What we do not stop, and we want this called out plainly:

  • Hot rows in the RedDB process memory are plaintext after decrypt. A root-shelled attacker can gcore the process and recover plaintext for any data the process has recently read.
  • Master keys are in process memory while the process is running. We zero them on shutdown and on rotation, but a live process holds live keys.

Defences (operational, not cryptographic):

  • Least privilege: nobody has interactive shell on production RedDB nodes; access is brokered, audited, time-boxed.
  • BYOK with a customer-held KMS turns this from “the vendor can read your data if compromised” into “the vendor can read your data only while a session against your KMS is active”. The customer can pull the KMS grant and the next key-cache eviction renders the engine unable to decrypt new generations.
  • HSM-backed KMS with remote-unwrap (HYOK) reduces this further; we mention it but it is not the default.

I.4 — Data in memory, in the application process

Attacker: anyone who can compromise your application.

What we stop: nothing. This is outside the boundary. The vault gives you plaintext when you ask for it through a legitimate client. A compromised application is a legitimate client.

Defences: yours. Process isolation, secrets management, request-scoped decryption (only decrypt the row the current request needs), and BYOK so a panic-revoke is possible.

D — Denial of service

Attacker: someone trying to make the database stop serving traffic.

What we stop or mitigate:

  • Per-tenant resource quotas. A noisy tenant cannot eat the whole node’s IO or memory budget; the scheduler enforces a fair-share with hard ceilings.
  • Connection-level rate limits at the gateway in front of the engine.
  • Backpressure under write pressure rather than unbounded queue growth; clients see slow-downs before the engine OOMs.

What we do not stop:

  • Volumetric attacks below the gateway. A real DDoS is a perimeter problem; the engine is not your edge.
  • An expensive-but-valid query pattern. Hybrid search with a deliberately bad filter selectivity will burn CPU. We surface that in query observability so you can detect and rate-limit it at the application layer, but the engine will execute what it is told.
  • Disk-fill from a privileged tenant. Quotas protect against tenant-vs-tenant, not against the cluster operator pushing the disk to 100%.

E — Elevation of privilege

Attacker: a low-privileged client trying to act as a higher-privileged one.

What we stop:

  • Tenant boundary. Every read and write carries a tenant identity derived from the mTLS subject; the planner refuses to return rows outside that tenant unless the caller has an explicit cross-tenant grant. This is enforced at the storage layer, not just in the API.
  • Row-level access checks. Where row-level grants are configured, they are evaluated after the vault decrypt but before the row leaves the process, so a query that touches forbidden rows still cannot exfiltrate them.

What we do not stop:

  • Misconfigured grants. If you grant * to a role, the engine will honour that grant. We log it loudly at config time but do not refuse it.
  • A compromised admin credential. Admin is admin. There is no cryptographic guard that a determined admin cannot turn off. The defence is admin hygiene plus an audit trail that an external observer can read after the fact.

What this means for buyers

If the regulator asks “is the data encrypted at rest” the answer is yes. That is not the interesting question. The interesting questions are below, with the answers:

QuestionRedDB’s answer
Can a stolen backup be opened without the master key?No.
Can a network observer between replicas read row contents?No.
Can a compromised RedDB process read hot rows?Yes, while it holds the keys.
Can a compromised application process read its own tenant’s rows?Yes, by definition — it is a legitimate client.
Can RedDB the vendor read your data?Only with valid KMS access. In BYOK mode, only while you grant it; pull the grant and we go dark on the next cache eviction.
Can an admin with shell rewrite audit history?Not silently — the audit log is vault-encrypted with a separate key generation, and you should mirror it to an external append-only store if you need regulator-grade non-repudiation.
Can the engine prevent a malicious operator on your side?No. That is your problem; we make it auditable.

If any “yes” in that table is unacceptable for your threat model, the mitigation is named in the relevant STRIDE section above. If a mitigation we name is still insufficient — for example, you need HYOK with remote-unwrap on every read — talk to us; that is a deployment shape we have built before but it is not the default.

What we are not claiming

To close the loop, an explicit list of things this engine does not do, that other vendors sometimes imply they do:

  • Homomorphic computation on encrypted data. We do not. Vault columns are decrypted in-process to be operated on.
  • Confidential-computing-style memory enclaves (SGX/SEV). Not a default. We have customers running RedDB inside an enclave for the I.3 attacker, but it is a deployment choice they make and operate; the engine does not require it.
  • Provable deletion across replicas. GDPR-style erasure works through crypto-shredding — destroy the key, the ciphertext becomes noise. This is the right answer for replicated systems but it is not the same as overwriting every copy of the plaintext bit-for-bit.
  • Defence against a state-level adversary with physical access. That is not a database problem.

Naming these gaps is the point of this post. A buyer who reads the security one-pager and does not see them listed should ask why.


This page is a snapshot. The cryptography, the audit-log shape, and the BYOK story are all moving targets; the boundary is not. If anything in the STRIDE walk changes, we update this post — it is the canonical reference we point security reviewers at, so it is in our interest to keep it honest.

Reviewed by RedDB’s security lead before publication. If you want the deeper write-up — full STRIDE matrix, deployment-shape variants, sample audit-stream consumer — it is on the docs site under security/threat-model.

© 2026 RedDB.io. AGPL-3.0 self-host · Managed Cloud.