Docs / Architecture & integration
Mask PII locally before it reaches any LLM
TrustNode is a local-first DevSecOps toolkit: @trustnode/core masks PII with deterministic tokens in your app, backend, CLI, or Chrome extension before text reaches LLM APIs. The TrustNode API syncs policy and quota — it does not receive raw prompts to mask. Masking always runs in your app, backend, CLI, or browser extension via @trustnode/core. The TrustNode API manages policy, quotas, and usage — it does not receive raw prompts to mask.
On this page
How TrustNode works
TrustNode is an egress firewall for AI: customer or employee text is tokenized before it leaves your environment toward ChatGPT, Claude, Gemini, or your own model providers.
- 1. Policy sync — Your app or extension calls
GET /v1/configwith a publishable key to learn which detectors and Brand Guard terms are enabled. - 2. Local mask — Before any outbound LLM call, run
maskPii()in-process (Node backend, edge worker, browser extension inject script, etc.). - 3. Safe egress — Only tokens like
[EMAIL_1]reach the model provider. - 4. Telemetry — Report
masked_countviaPOST /v1/telemetryso workspace quota stays accurate.
Mobile / Web / Server app Chrome (employees)
│ │
▼ ▼
Your backend ── maskPii(@trustnode/core) Extension inject ── same core engine
│ │
├─► OpenAI / Claude / Gemini ├─► chatgpt.com / claude.ai / …
│ │
└─► TrustNode API (config + quota) └─► TrustNode API (config + quota)What it detects
High-precision detectors (regex + validators such as Luhn / IBAN / TC kimlik). Designed to avoid shredding normal prose.
| Kind | Examples |
|---|---|
| user@company.com | |
| creditCard | 4111… (Luhn) |
| iban | TR… / DE… |
| phone | +90…, US, national |
| tr-tckn | 11-digit Turkish ID |
| nationalId | US SSN, UK NINO, ES DNI, … |
| passport / taxId | Passport & tax ID patterns |
| ipAddress / macAddress | IPv4/IPv6, MAC |
| Brand Guard | Competitors & custom terms |
SDK integration (web, mobile, backend)
For product AI assistants — whether the UI is a mobile app, web app, or internal tool — run masking on your server (or a trusted BFF) with @trustnode/core. Do not put API keys in mobile binaries.
# Private beta: @trustnode/core is not on the public npm registry yet. # After waitlist access we share a tarball / private registry invite, or you # link the package from the TrustNode monorepo: # # npm install ../path/to/packages/trustnode-core-sdk # # or in package.json: "@trustnode/core": "file:../trustnode-core-sdk"
import { maskPii, unmaskPii } from '@trustnode/core';
// Run in YOUR process (backend, BFF, or edge) — not as a remote "mask this text" API call.
const vault = new Map();
async function handleUserMessage(userText) {
const { output: masked, matches } = maskPii(userText, {
vault,
kinds: ['email', 'creditCard', 'phone', 'iban', 'tr-tckn', 'nationalId'],
});
// Only the masked prompt ever reaches the external LLM.
const llmReply = await callYourLlm(masked);
// Restore originals before showing the user (optional).
return { reply: unmaskPii(llmReply, vault), entitiesMasked: matches.length };
}Backend proxy pattern (recommended)
// Recommended for mobile + web apps:
// Mobile/Web client → your backend → maskPii(@trustnode/core) → OpenAI / Claude / Gemini
//
// Auth: use the same publishable key (tn_pub_…) as Browser Shield for config + telemetry.
// tn_secret_… is optional on paid plans for server-only clients — never ship it to browsers/mobile.
//
// 1) Fetch workspace policy (cache briefly; respect quotaExceeded)
const config = await fetch('https://api.trustnodehq.com/v1/config', {
headers: { Authorization: `Bearer ${process.env.TRUSTNODE_PUBLISHABLE_KEY}` },
}).then((r) => r.json());
// 2) Mask locally with the same engine the Chrome extension uses
const { output, matches } = maskPii(req.body.prompt, {
kinds: Object.entries(config.default_rules ?? {})
.filter(([, enabled]) => enabled)
.map(([kind]) => kind),
brandGuard: { customTerms: config.brand_guard_terms ?? [] },
});
// 3) Call the LLM with masked text only
// 4) Report usage so dashboard Home / Billing quota stays accurate
await fetch('https://api.trustnodehq.com/v1/telemetry', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TRUSTNODE_PUBLISHABLE_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
masked_count: matches.length,
events: [{ at: Date.now(), platform: 'my-app', masked_count: matches.length }],
}),
});API Gateway reference
Base URL: https://api.trustnodehq.com (live control plane). Create keys in the dashboard → API Keys. Use a publishable tn_pub_… key for Browser Shield and for backend /v1/config + /v1/telemetry. Optional tn_secret_… keys are for trusted servers on Startup+ plans — never ship them to browsers or mobile apps. Revoking a key does not reset workspace quota or audit history.
| Endpoint | Purpose |
|---|---|
| GET /v1/config | Policy (default_rules), Brand Guard terms, tier, quota snapshot |
| POST /v1/telemetry | Report masked_count / entities_masked; deducts monthly quota (rate-limited) |
| GET /health | Liveness check |
Fetch policy:
curl -s https://api.trustnodehq.com/v1/config \ -H "Authorization: Bearer tn_pub_YOUR_KEY"
Report usage:
curl -s -X POST https://api.trustnodehq.com/v1/telemetry \
-H "Authorization: Bearer tn_pub_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"masked_count": 3}'Browser Shield (Chrome extension)
For employees using ChatGPT, Claude, Gemini, and similar sites in Chrome, TrustNode Shield runs the same core engine in the page (main-world inject). Masking happens on the device before the browser POST leaves. The extension does not use your dashboard login session — it authenticates with a tn_pub_… publishable key and only calls the TrustNode API for policy + usage telemetry.
- Sign up / sign in at app.trustnodehq.com
- Open API Keys → generate a publishable key (
tn_pub_…). Copy it immediately — it is shown once. - Install TrustNode Shield (Chrome), open the popup, paste the key, click Save.
- Wait for Connected. Without a key, masking stays off.
- Use ChatGPT / Claude as usual — PII is replaced with tokens like
[EMAIL_1]before the request leaves the browser. Usage appears on the dashboard Home gateway counter.
Embedding TrustNode in your own product? Same local engine + API Gateway pattern — see API Gateway and SDK integration.
CLI scan (PLG)
Freemium local repo scan finds exposed PII, shows blurred teasers in the terminal, and opens a magic-link risk report. Detection still runs locally via @trustnode/core.
# Private beta: @trustnode/cli is not on the public npm registry yet. # From the TrustNode monorepo (after npm install in packages/trustnode-core-sdk): cd apps/trustnode-cli npm install export TRUSTNODE_API_URL=https://api.trustnodehq.com export TRUSTNODE_DASHBOARD_URL=https://app.trustnodehq.com npm run scan -- .
Brand Guard
Redact custom dictionary terms locally before egress — no extra LLM classification step. Workspace terms from the dashboard arrive as brand_guard_terms on GET /v1/config.
import { maskPii } from '@trustnode/core';
// Dashboard Policies → Brand Guard terms sync via GET /v1/config as brand_guard_terms.
// Pass them as customTerms (flat deny-list). Advanced competitor splits are SDK-only for now.
const { output } = maskPii("Share the Project Nightingale deck with finance.", {
brandGuard: {
customTerms: ['Project Nightingale'], // e.g. config.brand_guard_terms
},
});
// Matched terms are redacted locally — never vaulted.Tokenization & Vault
Replace PII with stable tokens for the model, then restore originals for the end user with the same vault map.
import { maskPii, unmaskPii } from '@trustnode/core';
const vault = new Map();
const userInput = "Contact jane@example.com about the new project.";
const masked = maskPii(userInput, { vault });
// masked.output -> "Contact [EMAIL_1] about the new project."
const llmResponse = `I drafted a note for ${masked.output}`;
const finalOutput = unmaskPii(llmResponse, vault);
// Restores [EMAIL_1] → jane@example.com for the end user only.Next steps
SDK integration
Wire @trustnode/core into your backend before LLM calls.
API Gateway
Config, telemetry, auth, and quotas.
Browser Shield
Protect employee chats on ChatGPT, Claude, and more.
Compliance presetsSoon
GDPR / HIPAA packing profiles.
FAQ
Architecture and integration questions.
- Does the TrustNode API mask my text in the cloud?
- No. Masking always runs locally with @trustnode/core inside your backend, app, CLI, or Chrome extension. The API (GET /v1/config, POST /v1/telemetry) syncs policies and usage quotas only — raw prompts are not uploaded to TrustNode for masking.
- How do I protect a mobile or web AI assistant?
- Send user messages to your own backend first. Call maskPii() there with @trustnode/core, then forward only the masked text to OpenAI, Claude, or Gemini. Sync policy via GET /v1/config and report usage with POST /v1/telemetry using a publishable tn_pub_ key. Never put API keys in the mobile/web binary.
- How does the Chrome extension relate to the API?
- Browser Shield uses the same core engine in the page to mask ChatGPT, Claude, and similar sites before the browser request leaves the device. It calls the TrustNode API only for workspace config and telemetry — not to mask chat content remotely. Paste a tn_pub_ key from Dashboard → API Keys.
- Can I install @trustnode/core from npm today?
- Not from the public npm registry yet — TrustNode is in private beta. After waitlist access we share a tarball or private registry invite; evaluators can also link the package from the TrustNode monorepo. The live API gateway at api.trustnodehq.com already serves config and telemetry.
- Does revoking an API key reset my quota?
- No. Usage and monthly quota live on the workspace, not on the key. Revoke + create a new tn_pub_ key only rotates credentials; Home usage and audit history stay intact.
- What is TrustNode?
- TrustNode is a local-first DevSecOps toolkit: @trustnode/core masks PII with deterministic tokens in your app, backend, CLI, or Chrome extension before text reaches LLM APIs. The TrustNode API syncs policy and quota — it does not receive raw prompts to mask.
- What is deterministic tokenization?
- The same input value consistently maps to the same token (for example [CREDIT_CARD_1]) within a vault session, so debugging and support stay possible without sending raw PII to the model.