← back to Fleet Rag
fleet-rag: redact secret shapes at ingest + untrack vectors.jsonl build artifact
114cc098803822112d5595ce729f1acb8f0f5de3 · 2026-06-24 08:52:22 -0700 · Steve
Files touched
M .gitignoreM lib/index.jsA lib/redact.js
Diff
commit 114cc098803822112d5595ce729f1acb8f0f5de3
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jun 24 08:52:22 2026 -0700
fleet-rag: redact secret shapes at ingest + untrack vectors.jsonl build artifact
---
.gitignore | 3 +++
lib/index.js | 2 ++
lib/redact.js | 26 ++++++++++++++++++++++++++
3 files changed, 31 insertions(+)
diff --git a/.gitignore b/.gitignore
index 19e99af..75f37ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,6 @@ build/
*~
.swp
.swo
+
+# RAG build artifact — regenerable via POST /index, NEVER commit (holds spilled secrets)
+data/vectors.jsonl
diff --git a/lib/index.js b/lib/index.js
index a7a6ff3..c5e5de9 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -4,6 +4,7 @@ const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const { embed } = require('./embed');
+const { redact } = require('./redact');
const VECTORS_PATH = path.join(__dirname, '../data/vectors.jsonl');
const CHUNK_SIZE = 512;
@@ -162,6 +163,7 @@ async function buildIndex(onProgress) {
for (let i = 0; i < all.length; i++) {
const doc = all[i];
+ doc.chunk_text = redact(doc.chunk_text); // strip known secret shapes before embed/persist
try {
const embedding = await embed(doc.chunk_text);
const record = { id: i, ...doc, embedding };
diff --git a/lib/redact.js b/lib/redact.js
new file mode 100644
index 0000000..fec7896
--- /dev/null
+++ b/lib/redact.js
@@ -0,0 +1,26 @@
+'use strict';
+// Redact known fleet-secret shapes from any chunk before it is embedded/persisted.
+// Added 2026-06-24 (fleet-rag-secret-spillage remediation): the ingestion pipeline
+// slurped server.js heads + memory files verbatim, capturing plaintext secrets into
+// data/vectors.jsonl. This filter neutralizes known secret shapes at ingest time so a
+// rebuilt index carries no live credential even when a source file still holds one.
+const PATTERNS = [
+ [/AIza[A-Za-z0-9_\-]{35}/g, '[REDACTED_GEMINI_KEY]'],
+ [/shpat_[a-f0-9]{32}/g, '[REDACTED_SHOPIFY_TOKEN]'],
+ [/shpss_[a-f0-9]{32}/g, '[REDACTED_SHOPIFY_SECRET]'],
+ [/shpca_[a-f0-9]{32}/g, '[REDACTED_SHOPIFY_SECRET]'],
+ [/https?:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9\/]+/g, '[REDACTED_SLACK_WEBHOOK]'],
+ [/postgres(?:ql)?:\/\/[^:\/\s]+:[^@\s]+@[^\s"'`]+/g, '[REDACTED_PG_DSN]'],
+ [/DW2024SecurePass!?/g, '[REDACTED_PW]'],
+ [/DWSecure2024!?/g, '[REDACTED_PW]'],
+ [/[A-Za-z0-9]*access911[A-Za-z0-9]*/g, '[REDACTED_VENDOR_PW]'],
+ [/sk-[A-Za-z0-9]{20,}/g, '[REDACTED_OPENAI_KEY]'],
+ [/(?:r8_|ghp_|gho_|xoxb-|xoxp-)[A-Za-z0-9\-]{20,}/g, '[REDACTED_TOKEN]'],
+];
+function redact(text) {
+ if (!text) return text;
+ let out = String(text);
+ for (const [re, repl] of PATTERNS) out = out.replace(re, repl);
+ return out;
+}
+module.exports = { redact };
← 854e00f gitignore: cover backup/scratch/editor artifacts
·
back to Fleet Rag
·
untrack vectors.jsonl build artifact (held spilled secrets) b21a822 →