PouchDB Encryption Plugin

4.0.2 · active · verified Wed Apr 22

Crypto-Pouch is a PouchDB plugin designed to provide transparent, field-level encryption for document data stored in PouchDB and CouchDB databases. It currently operates at version 4.0.2 and integrates seamlessly with existing PouchDB instances. The plugin leverages the TweetNaCl.js library, an independently audited cryptographic library, utilizing the xsalsa20-poly1305 algorithm for robust authenticated encryption. Once initialized with a password, it transparently encrypts document contents on write operations and decrypts them on read operations, transforming the original document into a 'payload' property containing the ciphertext. A key differentiation is its explicit focus on document *contents*, leaving `_id`s, `_rev`s, and PouchDB view keys/values unencrypted. Attachments are also not encrypted by default, requiring careful consideration for applications needing full data at rest encryption. While a formal release cadence isn't published, updates are typically released as needed for maintenance or feature enhancements.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to initialize `crypto-pouch` on a PouchDB database, add and retrieve encrypted documents, and highlights the recommended approach for handling unencrypted attachments.

const PouchDB = require('pouchdb');
PouchDB.plugin(require('crypto-pouch'));

async function setupEncryptedDb(dbName, password) {
  const db = new PouchDB(dbName);

  // Initialize encryption; documents will be transparently en/decrypted after this.
  // Make sure to use a strong password for security.
  await db.crypto(password).then(() => {
    console.log('Database encryption enabled.');
  });

  // Example usage: putting and getting an encrypted document
  const docId = 'mydoc';
  const originalDoc = { _id: docId, message: 'hello world', sensitiveData: 'top secret' };
  await db.put(originalDoc);
  console.log('Document put:', originalDoc);

  const fetchedDoc = await db.get(docId);
  console.log('Document fetched (decrypted):', fetchedDoc);

  // Showing a limitation: attachments are not encrypted by default.
  // The README notes db.putAttachment/db.getAttachment are not supported.
  // Instead, manage attachments directly within the document object:
  await db.put({
    _id: docId,
    _attachments: {
      'myAttachment.txt': {
        content_type: 'text/plain',
        data: Buffer.from('Hello, world! Attachment not encrypted.').toString('base64')
      }
    }
  });
  console.log('Document with unencrypted attachment put.');

  // Remove encryption (forgets password, but existing docs remain encrypted)
  // db.removeCrypto();
  // console.log('Encryption removed.');

  return db;
}

// Example execution (replace with your actual database name and password)
setupEncryptedDb('my_encrypted_db_quickstart', process.env.DB_PASSWORD ?? 'myStrongPassword123!')
  .then(db => console.log('Setup complete for database:', db.name))
  .catch(err => console.error('Error during quickstart setup:', err));

view raw JSON →