Keep customer data encrypted, even from your own database.
ShrouDB is a security server you run next to your application. Your code calls it to encrypt sensitive fields, store secrets, sign users in, and check permissions. Your database holds only ciphertext. ShrouDB holds the keys and logs every access.
// Before: the SSN is stored in Postgres as plaintext
await sql`INSERT INTO customers (id, ssn) VALUES (${id}, ${ssn})`;
// After: Postgres only ever sees ciphertext. The key stays in ShrouDB.
const { ciphertext } = await shroudb.cipher.encrypt("customers", b64(ssn));
await sql`INSERT INTO customers (id, ssn) VALUES (${id}, ${ciphertext})`;Built for teams that handle data they can't afford to leak.
If your product stores health records, financial details, identity documents, or other personal data, you're expected to encrypt it, control who can read it, and show an auditor that you did.
Teams usually piece that together from a key management service, a secrets manager, an auth provider, and logs from each of them, then write and maintain the code that connects them. Every piece has its own credentials, its own permission model, and its own way of failing.
ShrouDB provides those pieces as one server you host: one config file, one set of access tokens, and one audit log. You can turn on a single feature, such as field encryption, and add others when you need them.
How it works
ShrouDB runs as a single server called Moat. You start it, point your app at it, and decide what each part of your system is allowed to do.
Run the server
One binary, or the shroudb/moat Docker image. It stores its data on local disk, encrypted under a master key you generate.
$ brew install shroudb/tap/shroudb-moat
$ export SHROUDB_MASTER_KEY=$(openssl rand -hex 32)
$ shroudb-moat --config moat.tomlCall it from your code
SDKs for TypeScript, Python, Go, and Ruby. Anything else can use the HTTP API or the RESP3 wire protocol.
import { ShrouDB } from "@shroudb/sdk";
const shroudb = new ShrouDB({
moat: "http://localhost:8200",
token: process.env.SHROUDB_TOKEN,
});Give each service only what it needs
Each access token is limited to the engines and namespaces it needs, read-only where possible. Every call is recorded in the audit log.
[access.policies.web]
token = "${WEB_APP_TOKEN}"
scopes = [
"cipher:customers/*", # use the customers keyring
"keep:*/READ", # read secrets, never change them
]What you can use it for
Each feature is a separate engine inside the server. Turn on the ones you need in your config and leave the rest off.
Encrypt customer data before it reaches your database
Encryption and signing. Your app never holds a key.
How it works →Add sign-up, login, and sessions
User accounts, passwords, sessions, and JWTs.
How it works →Get database passwords and API keys out of .env files
Versioned, encrypted secrets with path-based access.
How it works →Search data you've encrypted
Exact, prefix, contains, and fuzzy search over encrypted fields.
How it works →Store user files you can permanently delete
Encrypted file storage on S3 with cryptographic deletion.
How it works →Answer “who accessed this, and when?”
A tamper-evident audit log of every operation.
How it works →Decide who is allowed to do what
Policy-based authorization with signed decisions.
How it works →Issue TLS certificates for your internal services
An internal certificate authority.
How it works →Notify people whose contact details you store encrypted
Delivery to encrypted recipients.
How it works →Underneath them all is an encrypted, versioned key-value store, which you can also use directly for any other data you need to keep private.
What it replaces
You don't have to switch everything at once. Most teams start with the one problem that's blocking them.
| You need to | Usually done with | In ShrouDB |
|---|---|---|
| Encrypt fields in your database | AWS KMS or Vault Transit, plus code to call it | Cipher |
| Keep credentials out of config files | Vault KV, a cloud secrets manager, or .env files | Keep |
| User accounts and sessions | Auth0, Cognito, or your own tables | Sigil |
| Search encrypted columns | Decrypt everything to search, or leave the column unencrypted | Veil |
| Prove who accessed what | Logs spread across each of the services above | Chronicle |
| TLS certificates for internal services | step-ca or hand-run OpenSSL | Forge |
Why you can trust it with your keys
A security server should be held to a higher standard than the systems it protects. These are the rules ShrouDB is built to.
Nothing is written to disk unencrypted
There is no plaintext mode to forget to turn off. Every record is encrypted with AES-256-GCM before it reaches storage.
One master key to protect
Each engine and namespace gets its own key, derived from a single master key with HKDF. Keep the master key in your KMS or HSM and pass it in at startup.
Tokens carry only the access they need
Each access token is limited to specific engines and namespaces, with read, write, or admin access. Your web app can use one keyring and read secrets without being able to change them.
Fails closed
Requests without a valid token are rejected. If stored data fails an integrity check on startup, ShrouDB stops instead of serving it.
Plaintext doesn't linger
Keys and decrypted values are held in containers that wipe their memory when released. Core dumps are disabled, so a crash can't write keys to disk.
An audit log you can check
Audit events are hash-chained. Chronicle's VERIFY command reports whether any entry was changed or removed.
Where it runs
The API and SDKs are the same in both, so moving from one to the other means changing a URL and a token.
Run it on your own servers or in your own cloud account, so keys and data never leave your network.
- Single binary or Docker image
- All engines in one process, or split out to separate processes as you grow
- HTTP on port 8200, RESP3 on port 8201
- TLS and OpenTelemetry export
We run the server for you. Start on the free tier and move to self-hosting later without changing your code.
- Free tier for development and small projects
- Upgrades, backups, and TLS handled for you
- Usage-based pricing
Try it on your laptop.
The quickstart installs the server, encrypts a value, stores a secret, and reads back the audit log. It takes about five minutes.