Architecture
How the server, its engines, and its storage fit together.
Overview
Moat is one process. Requests arrive over HTTP or RESP3, pass an access check, and are routed to an engine. Every engine keeps its data in the same encrypted storage layer, in its own namespace, and records its operations to Chronicle.
HTTP :8200 ─┐
├─▶ token + scope check
RESP3 :8201 ─┘ │
▼
┌──────────┬──────────┬──────────┬───────────┐
│ Cipher │ Sigil │ Keep │ Veil │
│ Stash │ Sentry │ Forge │ Courier │
│ Chronicle│ ShrouDB key-value store │
└──────────┴──────────┴──────────┴───────────┘
│
▼
encrypted write-ahead log + snapshots
(AES-256-GCM, keys derived per namespace)How engines depend on each other
- Veil, Stash, and Courier use Cipher for their keys.
- Sigil uses Cipher to encrypt sensitive fields, Veil to make fields searchable, Keep for secrets, and Sentry for authorization.
- Cipher, Keep, Sentry, and the others send audit events to Chronicle.
- When engines run inside Moat, these calls happen in-process, with no network hop.
Embedded or remote
Each engine runs either embedded (the default: inside Moat, sharing its storage) or remote (as its own process, with Moat forwarding commands to it over RESP3). Clients don't see the difference, so you can move a busy engine onto its own machine without changing application code.
Storage
Encrypted write-ahead log
Every change is encrypted with AES-256-GCM and appended to a write-ahead log, with periodic snapshots. On restart, Moat loads the latest snapshot and replays the log after it. If a record fails its integrity check, recovery stops rather than skipping it.
Keys
Storage keys are derived from the master key with HKDF, separately for each namespace. Engines can't read each other's data.
Protocols
HTTP
POST /v1/{engine} with a JSON body of {"args": ["COMMAND", ...]} and a bearer token. Sigil also serves REST endpoints under /sigil/ for login and token refresh.
RESP3
A binary framing protocol on port 8201. Clients send AUTH <token>, then commands prefixed with the engine name, such as CIPHER ENCRYPT customers <base64>. The SDKs use RESP3 for direct connections and HTTP for Moat.
Observability
- Structured logs to stdout.
- An audit file at
<data_dir>/audit.log. - Traces exported over OTLP when
server.otel_endpointis set. - Queryable, hash-chained audit events in Chronicle.