npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aegis-lock

v2.1.0

Published

Database-agnostic client-side AES-256-GCM field-level encryption. Works with Supabase, MongoDB, or any database via pluggable adapters.

Downloads

322

Readme

aegis-lock

npm version License: MIT

Database-agnostic client-side AES-256-GCM field-level encryption with Contextual Binding and Blind Indexing.

Encrypt sensitive fields before they leave the browser or server. Decrypt after select. Zero plaintext hits the wire or your database. Works with Supabase, MongoDB, or any database via custom adapters.

⚠️ SECURITY WARNING: aegis-lock provides the cryptographic primitives, but you are responsible for your keys. Never hardcode CryptoKey exports in your source code. Always use a secure Key Management Service (KMS) or strict, vault-backed environment variables to inject your keys at runtime.

Requirements

  • Node.js 18+ (or any environment supporting the standard Web Crypto API, such as modern browsers, Cloudflare Workers, or Vercel Edge functions).

Install

npm install aegis-lock

Quick Start — Supabase

import { createClient } from "@supabase/supabase-js";
import { AegisClient, SupabaseAdapter, generateKey, generateBidxKey, exportKey } from "aegis-lock";

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
const adapter = new SupabaseAdapter(supabase);

// Generate your master encryption key and searchable blind index key
const key = await generateKey();
const bidxKey = await generateBidxKey(); 

// Export and save these securely! e.g., await exportKey(key)

const aegis = new AegisClient({
  adapter,
  primaryKeyField: "record_id", // REQUIRED: Binds ciphertext to the row to prevent tampering
  encryptedFields: {
    secure_fields: ["encrypted_content", "ssn", "email"]
  },
  bidxFields: {
    secure_fields: ["email"] // Optional: Creates an 'email_bidx' column for searching
  }
}, key, bidxKey);

// 1. Insert — fields are auto-encrypted. 
// Note: You MUST provide the primary key application-side!
await aegis.insert("secure_fields", {
  record_id: "uuid-1234-5678", 
  email: "[email protected]",
  encrypted_content: "Top secret",
});

// 2. Select — Aegis automatically hashes the email to search the 'email_bidx' column securely
const { data } = await aegis.select("secure_fields", { 
  column: "email", 
  value: "[email protected]" 
});

// 3. Update — automatically re-encrypts with a new IV and updates the blind index
await aegis.update("secure_fields", {
  record_id: "uuid-1234-5678", // Must include the primary key!
  email: "[email protected]",
  encrypted_content: "New secret"
});

// 4. Delete — Aegis automatically hashes the email to find the correct row to delete
await aegis.delete("secure_fields", {
  column: "email",
  value: "[email protected]"
});

Quick Start — MongoDB

import { MongoClient } from "mongodb";
import { AegisClient, MongoDBAdapter, generateKey } from "aegis-lock";
import { v4 as uuidv4 } from "uuid";

const mongo = new MongoClient("mongodb://localhost:27017");
await mongo.connect();
const adapter = new MongoDBAdapter(mongo.db("myapp"));

const key = await generateKey();

const aegis = new AegisClient({
  adapter,
  primaryKeyField: "_id", 
  encryptedFields: {
    users: ["ssn", "credit_card"]
  }
}, key);

const newUserId = uuidv4();

// 1. Insert with a client-generated ID
await aegis.insert("users", { 
  _id: newUserId, 
  name: "Alice", 
  ssn: "123-45-6789" 
});

// 2. Select by an unencrypted field
const { data } = await aegis.select("users", { 
  column: "name", 
  value: "Alice" 
});
// data[0].ssn → "123-45-6789" (decrypted)

// 3. Update — automatically re-encrypts the SSN with a new IV
await aegis.update("users", { 
  _id: newUserId, // Must include the primary key!
  name: "Alice", 
  ssn: "999-99-9999" 
});

// 4. Delete — Removes the record from the database
await aegis.delete("users", { 
  column: "_id", 
  value: newUserId 
});

Custom Adapter

Implement the DatabaseAdapter interface for any database:

import { DatabaseAdapter } from "aegis-lock";

class MyAdapter implements DatabaseAdapter {
  async insert(table: string, data: Record<string, unknown>) {
    // your insert logic
    return { data: [data], error: null };
  }
  async select(table: string, query?) {
    // your select logic
    return { data: [], error: null };
  }
  async update(table: string, data: Record<string, unknown>) {
    // your update logic
    return { data: [data], error: null };
  }
  async delete(table: string, query: { column: string; value: unknown }) {
    // your delete logic
    return { data: [], error: null };
  }
}

API

new AegisClient(config, key, bidxKey?)

  • configAegisConfig object:
    • adapter: any DatabaseAdapter (SupabaseAdapter, MongoDBAdapter, or custom)
    • primaryKeyField: string (The ID field used for cryptographic contextual binding)
    • encryptedFields: Record<tableName, fieldName[]>
    • bidxFields: (Optional) Record<tableName, fieldName[]>
  • keyCryptoKey from generateKey() or importKey()
  • bidxKey(Optional) CryptoKey from generateBidxKey() or importKey()

AegisClient Methods

  • insert(table, data): Encrypts data and creates blind indexes before saving.
  • select(table, query): Fetches and automatically decrypts data. Intercepts blind index queries.
  • update(table, data): Re-encrypts modified fields with new IVs and updates blind indexes.
  • delete(table, query): Intercepts queries to securely delete by blind-indexed fields.
  • selectRaw(table, query): Bypasses decryption to return raw database records (useful for auditing or migrations).

Adapters

  • new SupabaseAdapter(supabaseClient)
  • new MongoDBAdapter(mongoDb)

Crypto Utilities

  • generateKey() / generateBidxKey()
  • exportKey(key) / importKey(base64)

How It Works (Security Architecture)

  • Web Crypto API (AES-256-GCM): Runs natively in any modern browser or edge runtime.
  • Field-Level IVs: Every single encrypted field gets a unique, mathematically random Initialization Vector (IV) stored as a composite string (iv:ciphertext) to prevent keystream reuse attacks.
  • Contextual Binding (AAD): Ciphertexts are cryptographically bound to the row's primaryKeyField. If an attacker copies an encrypted SSN from User A and pastes it into User B's row, the decryption will strictly fail.
  • Blind Indexing (HMAC-SHA256): Because AES-GCM is non-deterministic (the same text encrypts differently every time), you cannot query standard encrypted fields. If configured via bidxFields, Aegis-Lock automatically generates deterministic, memory-aligned HMAC hashes. This allows you to search for exact matches (like looking up an email address) without exposing the plaintext to the database.
  • Database-agnostic: Swap adapters without changing your core application code.

License

MIT