KEY EXCHANGE…000
Skip to content

Docs

The engine, in practice.

Install, migrate an existing database, integrate it in your app. Everything fits on one page.

01

Overview

The QuorVault engine encrypts database columns with a hybrid scheme: X25519 + ML-KEM-768, combined through HKDF-SHA256, protect an AES-256 data key, which encrypts every value with AES-256-GCM, bound to its table, column and row.

It ships a command-line tool to migrate existing databases automatically, and a library for your application. The full guarantees are on the Security page.

02

Requirements

  • Node.js 24.7+ (ships OpenSSL 3.5, ML-KEM and Argon2id)
  • PostgreSQL (14+), MySQL (8.0+), MariaDB or SQLite
  • A single-column primary key on each migrated table

03

Installation

bash
npm install @quorvault/engine
npx quorvault --help

04

The fast way

bash
export DATABASE_URL="postgres://user:pass@host:5432/crm"   # or mysql://… or sqlite:file.db
export QUORVAULT_PASSWORD="…"   # otherwise prompted, hidden

# Is this machine, the database and the vault ready?
npx quorvault doctor

# Where is the personal data? (e-mails, phones, IBANs, cards, social security numbers…)
npx quorvault scan

# All-in-one for a table: vault, checks, rehearsal, encryption, search index, verification, report
npx quorvault protect --vault vault.json --table customers --columns email,phone --index email:lower

scan never prints the values it reads, only the kind of data it found. protect stops before writing if the rehearsal finds a problem, and resumes where it stopped when run again.

05

Step by step

bash
# Secrets stay out of your shell history
export DATABASE_URL="postgres://user:pass@host:5432/crm"
export QUORVAULT_PASSWORD="…"   # otherwise prompted, hidden

# 1. Create the vault (once per environment)
npx quorvault init --vault vault.json

# 2. Check the schema: column sizes, primary key, volume
npx quorvault plan --vault vault.json --table customers --columns email,phone

# 3. Dress rehearsal: reads and encrypts everything in memory, writes nothing
npx quorvault migrate --vault vault.json --table customers --columns email,phone --dry-run

# 4. Real migration (after a database backup)
npx quorvault migrate --vault vault.json --table customers --columns email,phone

# 5. Audit: every value must authenticate in its own row
npx quorvault verify --vault vault.json --table customers --columns email,phone

Each batch (500 rows by default) is locked, encrypted, verified and committed in one transaction. Re-running migrate resumes where it stopped. Columns that are too short or not text are flagged by plan; --alter-columns converts them to TEXT.

06

From a legacy cipher

bash
export OLD_KEY="<64 hex characters>"
npx quorvault migrate … --from aes-256-cbc --legacy-key-env OLD_KEY
npx quorvault migrate … --from aes-256-gcm:hex --legacy-key-env OLD_KEY

Supported formats: plaintext (default), aes-256-cbc, aes-256-gcm, with :hex when values are hex-encoded.

07

In your application

typescript
import { openVault } from "@quorvault/engine";

const qv = await openVault("vault.json", process.env.QUORVAULT_PASSWORD!);

// Write: token, plus a search fingerprint if the column is searchable
const { token, index } = qv.seal("alice@acme.io", { table: "customers", column: "email", row: 42 });

// Read
const email = qv.decrypt(row.email, { table: "customers", column: "email", row: row.id });

// Exact lookup on an encrypted column
db.query("SELECT * FROM customers WHERE email_bidx = $1", [qv.blindIndex(input, { table: "customers", column: "email" })]);

// During a rollout: accepts plaintext or ciphertext
const value = qv.decryptIfEncrypted(row.email, { table: "customers", column: "email", row: row.id });

The vault password is provided at startup, from an environment variable or a secrets manager.

09

PHP, Python, Java…: the local service

bash
export QUORVAULT_SERVE_TOKEN="$(openssl rand -base64 36)"
npx quorvault serve --vault vault.json          # http://127.0.0.1:8750

curl -s http://127.0.0.1:8750/v1/encrypt \
  -H "Authorization: Bearer $QUORVAULT_SERVE_TOKEN" -H "Content-Type: application/json" \
  -d '{"table":"customers","column":"email","row":42,"value":"alice@acme.io"}'

The service listens on the machine itself only, requires a token and sends no CORS headers. Endpoints: /v1/encrypt, /v1/decrypt, /v1/blind-index, with batching (items). Ready-made PHP and Python clients ship with the engine.

10

Key management

bash
npx quorvault info       --vault vault.json   # vault details
npx quorvault passwd     --vault vault.json   # change the password (data untouched)
npx quorvault rotate-key --vault vault.json   # new active data key
npx quorvault reencrypt  --vault vault.json --table customers --columns email,phone
npx quorvault revert     --vault vault.json --table customers --columns email,phone

Back up the vault and its password separately: without either, the data is permanently unreadable.

11

Token format

text
qv1.<base64url( keyId:uint32 ‖ nonce:12 bytes ‖ AES-256-GCM ciphertext ‖ tag:16 bytes )>

AAD = "quorvault/field/v1" ‖ vaultId ‖ keyId ‖ table ‖ column ‖ rowId   (length-prefixed)

ASCII text that fits in any TEXT column. A value copied elsewhere, or changed by a single byte, fails authentication.

12

Current limits

  • No SQL Server, Oracle or MongoDB yet. MySQL: InnoDB tables only.
  • Composite primary keys are not supported yet.
  • On encrypted columns: exact lookups only (through the fingerprint), no sorting or prefix search.