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

n8n-nodes-memory-postgres-chat-encrypted

v0.1.2

Published

n8n community node — Postgres chat memory with configurable AES-256-GCM (application-level) or pgcrypto (server-side) encryption at rest

Downloads

427

Readme

n8n-nodes-memory-postgres-chat-encrypted

n8n community node — Postgres Chat Memory with configurable AES-256-GCM (application-level) or pgcrypto (server-side) encryption at rest.

npm version License: MIT


Overview

This node extends the official n8n Postgres Chat Memory node with transparent, configurable encryption of AI agent chat history stored in PostgreSQL. The LangChain agent always receives plaintext messages; encryption and decryption are completely transparent.

| Mode | Encryption location | Algorithm | PG extension required | |------|---------------------|-----------|----------------------| | None (default) | — plaintext | — | No | | Application-level | Node.js process | AES-256-GCM | No | | pgcrypto | PostgreSQL server | OpenPGP / AES-256 | Yes (pgcrypto) |

When to use each mode

| Requirement | Recommended mode | |-------------|-----------------| | Backward compatible with existing Postgres Chat Memory data | none | | Encryption without server-side PG changes (e.g., managed cloud PG) | app | | Encryption delegated to the DB server (pgcrypto already installed) | pgcrypto |


Installation

In n8n

  1. Open Settings → Community Nodes
  2. Click Install
  3. Enter: n8n-nodes-memory-postgres-chat-encrypted
  4. Click Install and restart n8n

Via npm (self-hosted)

npm install n8n-nodes-memory-postgres-chat-encrypted

Requirements

  • n8n ≥ 1.x
  • Node.js ≥ 18
  • PostgreSQL ≥ 13
  • pgcrypto extension — only if using pgcrypto mode (CREATE EXTENSION pgcrypto;)

Usage

1. Add the node to your workflow

Connect Postgres Chat Memory (Encrypted) to your AI Agent node's Memory input, just like the standard Postgres Chat Memory node.

2. Configure the Postgres credential

Use an existing Postgres credential or create a new one. Click Test to verify the connection.

3. Configure the node parameters

| Parameter | Description | |-----------|-------------| | Session ID | Unique identifier per conversation. Use {{ $json.sessionId }} for dynamic sessions. | | Table Name | Table to store messages in (auto-created on first use). Default: n8n_chat_histories. | | Context Window Length | Number of past exchanges to include (0 = unlimited). | | Encryption Mode | None, Application-level (AES-256-GCM), or PostgreSQL pgcrypto. | | Encryption Key | Required when mode is not None. See Key Management. | | Key Input Type | Passphrase (PBKDF2-derived) or Raw 32-byte hex (app-level only). |


Key Management

⚠️ Security warning: The encryption key protects all stored chat history. Loss of the key means permanent data loss. Changing the key does not re-encrypt existing rows.

Application-level mode

Two key input types are supported:

Passphrase (recommended for simplicity)

  • Any UTF-8 string
  • A 32-byte AES key is derived via PBKDF2-SHA-256 (100 000 iterations, fixed salt)
  • Example: my-very-long-and-random-passphrase

Raw 32-byte hex (recommended for maximum security)

  • Exactly 64 hexadecimal characters representing a raw 32-byte key
  • No PBKDF2 derivation is applied
  • Generate with: openssl rand -hex 32

pgcrypto mode

  • The key is passed directly to pgp_sym_encrypt / pgp_sym_decrypt as a passphrase
  • pgcrypto uses OpenPGP symmetric encryption with AES-256
  • Key rotation requires re-encrypting all rows manually

Storing the key safely

Never store the key directly in the workflow JSON. Instead:

  1. n8n Generic Credential — create a Generic Auth credential with the key as a field, then reference it via an expression: {{ $credentials.myEncKey.key }}
  2. Environment variable — set MY_ENCRYPT_KEY and reference it via {{ $env.MY_ENCRYPT_KEY }}
  3. Vault integration — use an HTTP Request node to fetch the key from HashiCorp Vault or AWS Secrets Manager before the AI Agent node

Database Schema

The node auto-creates (and migrates) the table on first use:

CREATE TABLE IF NOT EXISTS n8n_chat_histories (
  id              SERIAL PRIMARY KEY,
  session_id      TEXT        NOT NULL,
  message         TEXT        NOT NULL,   -- JSON, "PGC:<base64>", or "APP:<base64>"
  encryption_mode VARCHAR(16),            -- 'none' | 'pgcrypto' | 'app' | NULL (legacy)
  created_at      TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_n8n_chat_histories_session_id
  ON n8n_chat_histories (session_id);

Sentinel prefixes

Each stored row is self-describing via a sentinel prefix:

| Prefix | Meaning | |--------|---------| | (none) | Plaintext JSON (mode: none or legacy) | | PGC: | pgcrypto-encrypted base64 | | APP: | AES-256-GCM encrypted base64 (iv \|\| tag \|\| ciphertext) |


Migrating from the original Postgres Chat Memory node

The none mode is 100% backward-compatible — it reads and writes the same row format as the original MemoryPostgresChat node. You can switch to this node without migrating any data.

Upgrading to encrypted mode

⚠️ Existing plaintext rows are not automatically re-encrypted when you switch modes. You must migrate data manually (see below) or accept mixed-mode rows (not supported — the strategy will throw on mismatched sentinel prefixes).

Migration script (application-level mode):

-- Step 1: Add the new columns (the node does this automatically, but you can do it manually)
ALTER TABLE n8n_chat_histories
  ADD COLUMN IF NOT EXISTS encryption_mode VARCHAR(16),
  ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ DEFAULT NOW();

-- Step 2: Re-encrypt existing rows using your preferred method
-- (Run a small n8n workflow that reads, re-encrypts, and updates each row,
--  or use a custom Node.js script that uses AppLevelStrategy directly.)

Security Considerations

  • AES-256-GCM provides authenticated encryption — any tampering with a stored ciphertext causes decryption to fail with an error.
  • Random 12-byte IV per message ensures that identical messages produce different ciphertexts.
  • pgcrypto mode requires the database server to handle the key material. Ensure the connection to Postgres uses TLS (ssl: true in the credential) to prevent key exposure in transit.
  • None mode with a table that has encrypted rows will throw an error — there is no silent downgrade.
  • The PBKDF2 salt is fixed (not per-row) in this implementation. For maximum security, prefer raw 32-byte hex keys (no PBKDF2 needed).

Development

# Install dependencies
npm install

# Build (TypeScript → dist/)
npm run build

# Unit tests (50 tests, no Docker required)
npm test

# Integration tests (18 tests, requires Docker)
npm run test:integration

# Local Postgres for manual testing
docker compose up -d
# psql postgresql://n8n:n8npass@localhost:5432/n8n_memory

# Lint
npm run lint

Performance

AES-256-GCM encrypt+decrypt round-trip: ~0.02 ms per message (well under the 5 ms NFR).


License

MIT — see LICENSE.