镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content
falkenslabPublic

Repository files navigation

pseudonym logo: a question mark between brackets, a person no one can name

pseudonym

Let your AI tools talk about people without ever naming them.
Each person becomes a stable alias like A-7K3F9Q, and only you can turn it back into a name, on your own machine.

npm Node.js 20+ TypeScript types No runtime dependencies License: MIT

📖 Documentation · 📖 Documentación en español

pseudonym is a pseudonymization library for programs that send data about people to a language model, such as an MCP server reading a course's submissions. Your program passes each person through it and sends A-7K3F9Q instead of "Ana Pérez"; free text loses its known names, emails, cards, IBANs and national ids on the way. The alias is an HMAC under a key that never leaves the machine, and a local encrypted directory lets the person in charge ask pseudonym whois A-7K3F9Q whenever they need to.

✨ Why pseudonym

  • 🕶️ The model never learns who is who. It can still tell people apart, refer to them and ask your program to act on them, by alias.
  • 🔑 Only you can undo it. Aliases come from a key on your machine; pseudonym whois answers offline, and nobody without the key can reverse them.
  • 🧷 Stable aliases. The same person always gets the same alias, even after changing their email.
  • 🧱 One alias per service. A student is one alias in the LMS and another in the mail, so a model can't join what it learns about them.
  • ✍️ Free text too. Names from the directory, emails, payment cards, IBANs and the checked national ids and phones of nine countries become aliases and placeholders.
  • 🧩 A library, not a server. It runs inside your program, with no runtime dependencies and no tool an agent could call to undo it.
  • 🧭 Honest about its limits. It's pseudonymization, not anonymization: the docs say what it doesn't catch and how to keep an agent away from the key.

🚀 Quick start

You need Node.js 20 or later and an ES module project.

npm install @falkenslab/pseudonym             # in your program
npm install --global @falkenslab/pseudonym    # the pseudonym command, for the people who run it
import { remember, resolve, redact } from "@falkenslab/pseudonym";

const service = "moodle@campus.example.org";

// Before a result reaches the model: people become aliases (one call for a whole list).
const aliases = await remember(users.map((user) => ({
  service,
  identifiers: { institutionalId: user.idnumber, email: user.email, serviceUserId: String(user.id) },
  displayName: user.fullname,
})));                                                   // ["A-7K3F9Q", ...]

// A write tool gets an alias back from the model.
const userId = await resolve("A-7K3F9Q", { service });  // keep it on your side

The key is created on first use, in %APPDATA%\pseudonym\ or ~/.config/pseudonym/. Back it up once with pseudonym key export.

🧪 A taste of the code

🔌 In an MCP server, everyone in a tool's result goes through remember(), and the model reads:

[{ "student": "A-9NQWD5", "grades": { "practice1": 8.5 } }, { "student": "A-TA8D1J", "grades": { "practice1": 6 } }]

✍️ Free text keeps its meaning and loses who wrote it:

await redact("Soy Marta Quiroga, mi móvil es 612 345 678 y mi SSN 123-45-6789.", { service, countries: ["ES", "US"] });
// "Soy A-9NQWD5, mi móvil es [PHONE_1] y mi SSN [US_SSN_1]."

👩‍🏫 In the person's terminal, without writing code:

pseudonym whois A-9NQWD5                                    # who an alias is
pseudonym redact < post.txt                                 # a text safe to paste into a chat
pseudonym reveal < answer.txt                               # the model's answer, with the names back
pseudonym remember --csv class.csv --only-aliases           # a class export, as aliases

A complete MCP server that does all of this over a made-up course is in examples/classroom-mcp.

🧰 What's inside

Area For example
🧷 Aliases remember() for one person or a list, per service or linked across services, first alias kept
🔙 The way back resolve() for write tools, pseudonym whois, reveal and resolve for the person
✍️ Redaction redact() with names from the directory, cards, IBANs and ids of ES, US, CA, DE, MX, CL, AR, BR and PT
🗂️ The directory AES-256-GCM by default, or plain JSON without a key where the OS protects the folder; safe across processes, link, forget, prune, migrate
🔑 The key Created on first use, key export, key import, key fingerprint, refuses to work if it goes missing
💻 The CLI Everything above without code, CSV in and out, --json for scripts

The API reference and the command reference list it all.

📚 Documentation

🛠️ Developing

npm install, then npm run typecheck && npm run lint && npm test; npm run docs:start previews the documentation site. The design decisions are in .minispec/, and each planned change has a note there and an issue here.

Made with 💖 by Falken's Lab Team

Releases

Contributors

Languages