ShrouDB
Getting started

Quickstart

Run ShrouDB on your machine, encrypt a value, store a secret, and see both in the audit log. About five minutes.

You'll run Moat (the ShrouDB server) with three engines: Cipher for encryption, Keep for secrets, and Chronicle for the audit log. Then you'll call it with curl and with the TypeScript SDK.

1. Install

terminal
$ brew install shroudb/tap/shroudb-moat

Prefer Docker? See Installation, then come back to step 2.

2. Write a config file

Save this as moat.toml. It creates a keyring called customers and two access tokens: an admin token, and an app token that can use the keyring and read secrets but not change them.

moat.toml
[server]
http_bind  = "127.0.0.1:8200"
resp3_bind = "127.0.0.1:8201"

[storage]
data_dir = "./moat-data"

[engines.cipher]
enabled = true

[engines.cipher.keyrings.customers]
algorithm     = "aes-256-gcm"
rotation_days = 90

[engines.keep]
enabled = true

[engines.chronicle]
enabled = true

[access.policies.admin]
token  = "${MOAT_ADMIN_TOKEN}"
scopes = ["*:*/*"]

[access.policies.app]
token  = "${APP_TOKEN}"
scopes = ["cipher:customers/*", "keep:*/READ"]

Engines you don't mention use their defaults. Add enabled = falseunder an engine's section to turn it off. Unknown keys are rejected at startup, so a typo fails loudly.

3. Generate a master key and tokens, then start

terminal
$ export SHROUDB_MASTER_KEY=$(openssl rand -hex 32)
$ export MOAT_ADMIN_TOKEN=$(openssl rand -hex 24)
$ export APP_TOKEN=$(openssl rand -hex 24)

$ shroudb-moat --config moat.toml

4. Encrypt and decrypt a value

Open a second terminal and export the same APP_TOKEN. Every engine is reachable at POST /v1/<engine> with the command and its arguments in an args array. Values are sent base64-encoded.

terminal
$ curl -s localhost:8200/v1/cipher \
    -H "Authorization: Bearer $APP_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"args":["ENCRYPT","customers","'"$(printf '123-45-6789' | base64)"'"]}'

The response contains ciphertext and the key_version that encrypted it. That ciphertext is what you store in your own database. To get the value back:

terminal
$ curl -s localhost:8200/v1/cipher \
    -H "Authorization: Bearer $APP_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"args":["DECRYPT","customers","<ciphertext>"]}'

The response's plaintext field is the original value, base64-encoded.

5. Store a secret, and see the app token refused

Store a secret with the admin token:

terminal
$ curl -s localhost:8200/v1/keep \
    -H "Authorization: Bearer $MOAT_ADMIN_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"args":["PUT","db/prod/url","'"$(printf 'postgres://app:pw@db/prod' | base64)"'"]}'

The app token can read it with ["GET","db/prod/url"]. Try the same PUT with $APP_TOKEN and Moat returns 403 with a DENIED error, because that token only has read access to Keep.

6. Read the audit log

terminal
$ curl -s localhost:8200/v1/chronicle \
    -H "Authorization: Bearer $MOAT_ADMIN_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"args":["QUERY","LIMIT","20"]}'

You'll see the encrypt, decrypt, and put operations from the steps above, with the token that made each one. ["VERIFY"]checks that the log's hash chain is intact.

7. Call it from your code

The SDKs wrap the same commands. The TypeScript SDK is published on GitHub Packages, so point npm at it once:

terminal
$ echo "@shroudb:registry=https://npm.pkg.github.com" >> .npmrc
$ npm install @shroudb/sdk
app.ts
import { ShrouDB } from "@shroudb/sdk";

const shroudb = new ShrouDB({
  moat: "http://localhost:8200",
  token: process.env.APP_TOKEN,
});

const b64 = (s: string) => Buffer.from(s).toString("base64");

const { ciphertext } = await shroudb.cipher.encrypt("customers", b64("123-45-6789"));
// store ciphertext in your database

const { plaintext } = await shroudb.cipher.decrypt("customers", ciphertext);
console.log(Buffer.from(plaintext, "base64").toString()); // 123-45-6789

await shroudb.close();

Python, Go, and Ruby SDKs follow the same method names.

Next steps

  • Browse the engines for user accounts, encrypted search, file storage, and the rest.
  • Read the Moat reference for every config option and the access token format.
  • Before going to production, work through the security checklist.