@vanar/veil-capsule
v0.1.2
Published
End-to-end encryption and tamper-proof audit trails for AI agents
Maintainers
Readme
@vanar/veil-capsule
End-to-end encryption and tamper-proof audit trails for AI agents.
Cryptography
- X25519 ECDH for key agreement
- XSalsa20-Poly1305 for authenticated encryption
- Ed25519 for digital signatures
All backed by TweetNaCl (audited NaCl implementation).
Install
npm install @vanar/veil-capsuleQuick Start
Encrypt / Decrypt
import { VeilClient } from '@vanar/veil-capsule';
const alice = new VeilClient();
const bob = new VeilClient();
// Alice encrypts for Bob
const encrypted = await alice.encrypt('secret message', bob.publicKey);
// Bob decrypts
const plaintext = await bob.decrypt(encrypted);
// => "secret message"
// Encrypt to self (for storage)
const selfEncrypted = await alice.encrypt('my data');
const selfDecrypted = await alice.decrypt(selfEncrypted);Sign / Verify
import { VeilClient } from '@vanar/veil-capsule';
const signingKeys = VeilClient.generateSigningKeyPair();
const signature = VeilClient.sign('important data', signingKeys.secretKey);
const valid = VeilClient.verify('important data', signature, signingKeys.publicKey);
// => trueVeilCapsule (Encrypted + Signed + Searchable Memory)
import {
VeilClient,
VeilCapsule,
InMemoryCapsuleBackend,
} from '@vanar/veil-capsule';
const capsule = new VeilCapsule({
veil: new VeilClient(),
memory: new InMemoryCapsuleBackend(),
signingKeyPair: VeilClient.generateSigningKeyPair(),
});
const userId = 'alice';
// Store: content is encrypted, metadata stays searchable
const entry = await capsule.store(
'sensitive agent memory',
{ topic: 'user preferences', agent: 'assistant-v2' },
userId,
);
// Search: keyword/relevance match on metadata, decrypt matching entries
const results = await capsule.search('preferences', userId);
console.log(results[0].decryptedContent);
// => "sensitive agent memory"
// Verify: check Ed25519 signature for tamper detection
const isValid = capsule.verify(entry);
// => trueBundled backends
| Backend | Ships in | Use case |
|---|---|---|
| InMemoryCapsuleBackend | core, zero deps | tests, demos, ephemeral agents, edge runtimes |
| PgCapsuleBackend | core, requires pg | production - records survive restarts, full-text search via tsvector |
import { PgCapsuleBackend, VEIL_CAPSULE_PG_SCHEMA } from '@vanar/veil-capsule';
import { Pool } from 'pg';
const capsule = new VeilCapsule({
veil: new VeilClient(),
memory: new PgCapsuleBackend({ pool: new Pool(), autoMigrate: true }),
signingKeyPair: VeilClient.generateSigningKeyPair(),
});MemoryBackend Interface
Implement this interface to plug VeilCapsule into any data store (Mongo, Redis, Supabase, your warehouse, anything):
interface MemoryBackend {
store(input: {
content: string;
metadata?: Record<string, unknown>;
externalUserId: string;
}): Promise<{ id: string }>;
query(input: {
prompt: string;
topK?: number;
externalUserId: string;
}): Promise<Array<{
id: string;
content: string;
metadata: Record<string, unknown>;
relevance: number;
createdAt: number;
}>>;
}externalUserId is required, non-empty - the backend uses it to isolate records per user/agent. Any custom backend must round-trip the metadata dict losslessly (VeilCapsule writes encrypted ciphertext and signatures into reserved _* keys and reads them back at query time).
Why VeilCapsule?
| Feature | Plain storage | VeilCapsule | |---------|--------------|-------------| | Encrypted at rest | No | Yes (XSalsa20-Poly1305) | | Tamper-proof | No | Yes (Ed25519 signatures) | | Semantic search | Depends | Yes (via MemoryBackend) | | Audit trail | No | Yes (signed entries) | | Backend agnostic | N/A | Yes (any MemoryBackend) |
License
Apache-2.0
