10.0 MixcoatlDB
A database that encrypts before it stores.
A sovereign database engine that encrypts before it stores. The carrier ledger holds ciphertext and nothing else.
- 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 is erasure
When your recipient acknowledges a delivery, the row's sender, recipient, and content fields are nulled in a single transaction, and the row is hard-deleted after a short grace window. A destroyed conversation goes further: its FSOR wrap key is retired, so any write-ahead residue stays locked under a key that no longer exists. The erasure story is cryptographic, not janitorial.
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 that ships
/// 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 | Cryptographic — retired epochs | 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?
Backups inherit the same shape: ciphertext under rotating at-rest keys, with FSOR-retired epochs unrecoverable.