10.0 MixcoatlDB
A database that encrypts before it stores.
A sovereign database engine that encrypts before it stores. The carrier ledger holds ciphertext; plaintext never reaches it.
- Audit log ML-DSA-87
- FSOR wrap HKDF-SHA512
- At-rest envelope ChaCha20-Poly1305
- Epoch commitment SHA-384
01 / THE APPEND PATH — LETTERED
Hand it a plaintext row. The append path refuses.
The encryption boundary
Your messages are sealed on your device, under Q-Ratchet, before they travel. The Mixcōātl carrier ledger sits behind that boundary: it receives ciphertext envelopes and opaque routing identifiers, and its write path has no plaintext column to fill. Applications never touch the storage substrate directly — every write crosses the carrier API, and the substrate can be swapped without the invariants moving.
- Envelope shape
- every INSERT requires (ciphertext, aad) — Q-Storage-Carrier
- Routing
- opaque UUIDs; cleartext participant identifiers quenched (migration 102)
- At-rest layer
- FSOR envelope wrap, HKDF-SHA512 per conversation epoch (spec §8)
The five ledger invariants
The ledger is defined by what it enforces, and each invariant is a named contract you can check against the source.
- Q-Storage-Carrier
- the append path refuses plaintext; INSERTs carry the (ciphertext, aad) shape
- Q-MetaSilence
- aggregate-only access counters; no per-row access logs
- Q-FS-AtRest
- at-rest keys rotate on a 24-hour cadence with re-encryption of prior WAL
- Q-PQ-Audit-Log
- operations signed under ML-DSA-87 and anchored to the transparency log
- Q-Sovereignty-Lock
- replication to foreign-cloud IP ranges is refused
Delivery, then deletion
When your recipient acknowledges a delivery, the relay marks the row deleted and hard-deletes it after a short grace window; a group message, sealed to each member by default, and a message read with Stealth Mode on or read receipts off wait for the offline horizon. Destroying a conversation deletes the rows the relay can tie to it. A one-to-one message, sealed by default, names neither its sender nor its conversation, so the destroy does not reach it: it leaves on the same clock as any message. The photos and files a conversation carried stay stored apart until their own expiry, unless their sender deleted them sooner. Nothing on the volume is overwritten. A row that arrived on the REST send lane also sat in an at-rest envelope, so once its conversation is destroyed, its write-ahead and backup residue stays under a retired epoch, whose key re-derives only from the operator master; rows from the other lanes rest on end-to-end encryption alone. FSOR wraps no file, and any server-side encryption a file’s store adds is under a key the operator holds, so against the operator a file rests on its end-to-end seal alone.
Undelivered messages queue with routing metadata under the published retention ladder — the server cannot read them, and it does not keep them longer than the ladder allows.
The append path has no plaintext column to fill.
02 / THE SOURCE — VERBATIM
Read the metadata engine in the source
/// Daily-rotated 32-byte salt for IP hashing. Rotation key is the UTC
/// calendar day at the time of `hash()`, so a query crossing midnight
/// will see two different hashes for the same IP. That is the property
/// that breaks long-window IP correlation in a forensic dump.
fn derive(base: &[u8; 32], day: NaiveDate, ip: IpAddr) -> String {
let mut h = Sha256::new();
h.update(b"QERYX-Q-MetaSilence-IP-v1");
h.update(base);
h.update(day.year().to_le_bytes());
h.update((day.month() as u32).to_le_bytes());
h.update((day.day() as u32).to_le_bytes());
match ip {
IpAddr::V4(v4) => {
h.update(b"v4");
h.update(v4.octets());
}
IpAddr::V6(v6) => {
h.update(b"v6");
h.update(v6.octets());
}
}
let digest = h.finalize();
hex::encode(&digest[..16])
}
03 / THE PARAMETERS — READ FROM SOURCE
Check every parameter against the file it came from
| Parameter | Value | Source |
|---|---|---|
| Envelope shape | (ciphertext, aad) required at INSERT | Q-Storage-Carrier |
| Access counters | aggregate-only, no per-user labels | backend/src/privacy.rs |
| IP handling | hashed under a daily 32-byte salt, 128-bit output | backend/src/privacy.rs |
| Timestamp precision | quantized to 5-minute windows | privacy.rs::quantize_to_window |
| Delivered-row purge | 10-minute grace, then hard DELETE | backend/src/handlers.rs |
| Audit signatures | ML-DSA-87 (FIPS 204), log-anchored | Q-PQ-Audit-Log |
| At-rest rotation | 24-hour cadence, prior WAL re-encrypted | Q-FS-AtRest |
| Replication policy | foreign-cloud IP ranges refused | Q-Sovereignty-Lock |
04 / THE YIELD — BY STORAGE CLASS
Seize the ledger. Read what it yields.
| QERYX Mixcōātl | Classical app database | Managed cloud DB | |
|---|---|---|---|
| Real workloads | |||
| Full database seizure | Ciphertext + routing metadata | Plaintext rows are common | Plaintext + provider access |
| Insider read | No plaintext path exists | DBA sees all | Provider and DBA see all |
| Access-pattern logging | Aggregate-only counters | Per-row logs | Provider telemetry |
| Replication policy | Sovereignty lock — refused ranges | Anywhere | Provider-controlled |
| Erasure | Hard DELETE; REST-lane residue under a retired epoch | DELETE plus residue | Provider snapshots persist |
05 / THE HARD QUESTIONS
Ask what a warrant on this ledger reaches.
What does the ledger hold?
Ciphertext envelopes, opaque routing identifiers, and epoch commitments. There is no plaintext column anywhere in the schema's write path.
What can a full database seizure yield?
Sealed envelopes plus routing metadata under the published retention ladder. Content requires breaking both X25519 and ML-KEM-1024.
Is this its own database engine?
It is a sovereign ledger abstraction with its own invariants and API. Applications never touch the storage substrate directly, and the substrate can be swapped without the invariants moving.
Who can query it?
Application code, through the carrier API only — and the audit log of operations is signed under ML-DSA-87 and externally anchored.
What about backups?
A backup holds what the live tables held when it was taken: end-to-end ciphertext beside the routing columns. A REST-lane row in it also sits in its at-rest envelope, and once its conversation is destroyed that epoch opens only for someone holding the operator master.