envelopa
v0.3.0
Published
Headless TypeScript library for end-to-end encrypted document storage
Maintainers
Readme
envelopa
Headless TypeScript library for building applications that store documents with end-to-end encryption.
Envelopa implements vault lifecycle, cryptographic envelopes, password-based key derivation, password rotation, and interoperable serialization. It does not provide authentication, databases, sync, networking, UI, or account management — those belong in your application layer.
Requirements
- Node.js >= 20 (or a modern browser with Web Crypto API)
- ESM (
"type": "module")
Development
From the monorepo root:
pnpm install
pnpm build
pnpm test:browserThe first run downloads Chromium via Playwright automatically (pretest:browser). If you see Executable doesn't exist, run manually:
pnpm --filter envelopa exec playwright install chromiumInstall
npm install envelopa @envelopa/argon2@envelopa/argon2 is required at runtime. Envelopa keeps the KDF in a separate package so the core stays runtime-neutral.
Quickstart
import { argon2id } from '@envelopa/argon2';
import {
createVault,
unlockVault,
encodeVaultHeader,
decodeVaultHeader,
envelopeToJson,
envelopeFromJson,
} from 'envelopa';
const kdfProvider = argon2id();
const password = 'user-chosen-password';
// Create a vault
const { header, session } = await createVault({
password,
kdfProvider,
});
// Persist the vault header (CBOR bytes — not plain JSON)
const headerBytes = encodeVaultHeader(header);
const headerB64 = Buffer.from(headerBytes).toString('base64url');
// Seal a document
const envelope = await session.seal({
documentId: 'note_123',
data: new TextEncoder().encode('secret content'),
context: { type: 'note' },
});
const envelopeJson = envelopeToJson(envelope);
session.destroy();
// --- later, in another session ---
const storedHeader = decodeVaultHeader(Buffer.from(headerB64, 'base64url'));
const unlocked = await unlockVault({
password,
header: storedHeader,
kdfProvider,
});
const plaintext = await unlocked.open(envelopeFromJson(envelopeJson));
console.log(new TextDecoder().decode(plaintext));
unlocked.destroy();Text helpers
For UTF-8 string content, use the envelopa/text subpath:
import { sealText, openText } from 'envelopa/text';
const envelope = await sealText(session, {
documentId: 'note_123',
text: '# Hello\n\nMarkdown here.',
});
const text = await openText(session, envelope);API surface
| Subpath | Exports |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| envelopa | createVault, unlockVault, encodeVaultHeader, decodeVaultHeader, encodeEnvelope, decodeEnvelope, envelopeToJson, envelopeFromJson, error types |
| envelopa/text | sealText, openText |
| envelopa/crypto | WebCryptoProvider, CryptoProvider type |
| envelopa/testing | DeterministicCryptoProvider (tests only — unsafe for production) |
VaultSession exposes seal, open, rotatePassword, and destroy. The concrete implementation is not exported.
Persistence
| Artifact | Format | Functions |
| ------------------ | ---------------------------------- | ----------------------------------------- |
| Vault header | Canonical CBOR bytes | encodeVaultHeader / decodeVaultHeader |
| Encrypted envelope | JSON (base64url for binary fields) | envelopeToJson / envelopeFromJson |
The in-memory VaultHeader type contains Uint8Array fields. Encode explicitly before storing in a database or file.
See docs/serialization.md for format details and persistence patterns.
Documentation
- Architecture — key hierarchy,
VaultSession, validation limits - Serialization — CBOR vs JSON, when to use each API
- Protocol v1 — wire formats, AAD, algorithms
Security scope
Protects against:
- Compromised database or storage provider (data at rest)
- Network interception of encrypted envelopes
- Malicious modification of persisted envelopes
- Offline password guessing (mitigated by Argon2id)
Does not protect against:
- Compromised client device or malicious JavaScript in your app origin
- Keyloggers or password theft
- Plaintext exposure while the vault session is unlocked
- Rollback attacks without external trusted versioning
See docs/architecture.md for a threat model summary. A formal threat model document is planned for 1.0.
Stability
0.3.0 completes protocol v1 test vectors, adds docs/protocol-v1.md, and migrates the repository to envelopa-dev/envelopa. The cryptographic protocol is versioned (version: 1), but the API may evolve before 1.0.0.
Specifications
Public documentation: docs/ (architecture, serialization, protocol v1).
License
MIT
