sgasser-llm-shield.git
2 weeks agofeat(dashboard): display secrets detection in logs table (#30)
Stefan Gasser [Fri, 16 Jan 2026 13:30:11 +0000 (14:30 +0100)]
feat(dashboard): display secrets detection in logs table (#30)

Add Secrets column to the Recent Requests table showing detected
secret types (e.g., OPENSSH_PRIVATE_KEY, PEM_PRIVATE_KEY) as red
badges. The data was already available from the API but not displayed.

- Add Secrets column header between PII Entities and Scan Time
- Parse secrets_types and secrets_detected from API response
- Display secret types as error-colored badges
- Add CSS utilities for error color variants
- Update colspan values for detail rows

Closes #20

3 weeks agoExclude test files from secret scanning (#31)
Stefan Gasser [Mon, 12 Jan 2026 15:48:24 +0000 (16:48 +0100)]
Exclude test files from secret scanning (#31)

Test files contain intentional fake secrets for testing secret detection.
This prevents false positive alerts for MongoDB connection strings and
other test fixtures in src/secrets/detect.test.ts.

3 weeks agoAdd environment variable credential detection (#19)
Max Wolf [Mon, 12 Jan 2026 15:02:29 +0000 (16:02 +0100)]
Add environment variable credential detection (#19)

* Add PatternDetector and DetectionResult interfaces for secrets detection registry

* Move pattern detection utility to new patterns/utils.ts module

* Refactor secrets detection using a registry system

- Create privateKeysDetector, apiKeysDetector, tokensDetector modules
- Refactor detectSecrets() to use the pattern registry
- Re-export types from detect.ts for backwards compatibility

* Change default secrets_detection action to redaction

Hint: The example config still shows `action: block` explicitly, with a comment noting
that `redact` is the default action if not specified

* Implement new pattern detector and add corresponding SecretEntityType options

* Register new detector and extend test suite accordingly

* Add new entity types to config.ts

* Update docs and example config

* Add environment variables section to secrets detection docs

---------

Co-authored-by: Stefan Gasser <redacted>
3 weeks agoAdd animated demo GIF to README and docs (#29)
Stefan Gasser [Mon, 12 Jan 2026 12:32:41 +0000 (13:32 +0100)]
Add animated demo GIF to README and docs (#29)

- New demo.gif showing the complete mask/unmask flow
- Embed in README hero section
- Add to docs introduction page

3 weeks agoAlways run language detection even with single language configured (#26)
Stefan Gasser [Mon, 12 Jan 2026 07:13:59 +0000 (08:13 +0100)]
Always run language detection even with single language configured (#26)

Previously, language detection was skipped when only one language was
configured, returning the configured language directly. This made it
impossible to detect misconfiguration (e.g., only EN configured but
receiving DE text).

Now language detection always runs, providing:
- Actual detected language in logs (detectedLanguage field)
- Confidence score for debugging
- usedFallback=true when detected language isn't configured

Performance impact is negligible (~0.01-0.05ms per detection).

3 weeks agoFix PII detection to scan all message roles (#25)
Stefan Gasser [Sun, 11 Jan 2026 18:42:09 +0000 (19:42 +0100)]
Fix PII detection to scan all message roles (#25)

Previously, PII detection only scanned the last user message initially,
then did a full scan only if PII was found. This caused PII in system
messages (e.g., RAG context from PDFs) to be missed entirely when the
user message contained no PII.

Changes:
- Consolidate analyzeMessages() to always scan all messages
- Scan system, developer, user, and assistant roles
- Remove analyzeAllMessages() as it's no longer needed
- Simplify decision.ts by removing the redundant full scan call

This ensures PII in system messages (common in RAG patterns) is properly
detected and masked before being sent to upstream LLMs.

Fixes #17

3 weeks agoRefactor secrets detection into pattern registry (#18)
Max Wolf [Sun, 11 Jan 2026 17:55:34 +0000 (18:55 +0100)]
Refactor secrets detection into pattern registry (#18)

* Add PatternDetector and DetectionResult interfaces for secrets detection registry

* Move all interfaces to patterns/types.ts and use the existing SecretesDetectionResult interface instead of the new DetectionResult

* Move pattern detection utility to new patterns/utils.ts module

* Refactor secrets detection using a registry system

- Create privateKeysDetector, apiKeysDetector, tokensDetector modules
- Refactor detectSecrets() to use the pattern registry
- Re-export types from detect.ts for backwards compatibility

* Change default secrets_detection action to redaction

Hint: The example config still shows `action: block` explicitly, with a comment noting
that `redact` is the default action if not specified

* Fix README default action references and improve overall structure / formatting

- Update all references from 'block (default)' to 'redact (default)'
- Fix Bearer token documentation (20+ → 40+ chars)
- Reorganize Configuration section with consistent headers
- Improve table formatting and section descriptions
- Use references to reduce duplications and maintenance overhead

* Improve type safety in PatternDetector interface

Use SecretEntityType instead of string for enabledTypes Set parameter

* Update docs to reflect redact as new default action

Reorder actions to show default first

---------

Co-authored-by: Stefan Gasser <redacted>
3 weeks agoAdd Mintlify documentation and simplify README (#24)
Stefan Gasser [Sun, 11 Jan 2026 10:11:54 +0000 (11:11 +0100)]
Add Mintlify documentation and simplify README (#24)

* Add Mintlify documentation and simplify README

Documentation:
- Add complete Mintlify docs with introduction, quickstart, integrations
- Add concept guides: mask mode, route mode, PII detection, secrets detection
- Add API reference: chat completions, models, status, dashboard API
- Add configuration guides: overview, providers, PII, secrets, logging
- Include dashboard screenshot and branding assets

README:
- Simplify structure, move detailed docs to Mintlify
- Add centered badges and navigation links
- Add "What is PasteGuard?" section explaining problem/solution
- Update example to Dr. Sarah Chen (consistent across all docs)
- Reorder integrations (OpenAI SDK, LangChain, LlamaIndex first)
- Move Presidio attribution inline with PII section
- Add Tech Stack section

Code:
- Update description to "Privacy proxy for LLMs" in package.json,
  startup banner, and /info endpoint

Closes #21

* docs: fix secrets default to block (matches current code)

3 weeks agofix: support developer and function roles for GPT-5.x compatibility (#23)
Stefan Gasser [Sun, 11 Jan 2026 09:14:06 +0000 (10:14 +0100)]
fix: support developer and function roles for GPT-5.x compatibility (#23)

GPT-5.x models use the 'developer' role instead of 'system' for
instructions. The 'function' role is also added for legacy compatibility.

Fixes #22

3 weeks agofeat: Update dashboard to match design system (#16)
Stefan Gasser [Sat, 10 Jan 2026 16:47:28 +0000 (17:47 +0100)]
feat: Update dashboard to match design system (#16)

* feat: Update dashboard to match design system

- Apply design system tokens (colors, typography, radius, shadows)
- Add branded "Redaction Bar Loader" animation for loading/empty states
- Add favicon route serving inline SVG
- Update README with wordmark SVG and optimized screenshot
- Move assets to assets/ folder (logo, wordmark, favicon, dashboard)

* fix: Formatting and browser compatibility fixes

- Fix biome formatting in favicon route (multi-line object)
- Add color-mix() fallback for card hover effect (older browsers)

3 weeks agoFix lint errors from multimodal PR (#11)
Stefan Gasser [Sat, 10 Jan 2026 14:00:48 +0000 (15:00 +0100)]
Fix lint errors from multimodal PR (#11)

- Remove unused imports in multimodal.test.ts
- Remove unused secretsConfig variable
- Fix import ordering in masking.ts and content.test.ts
- Remove trailing whitespace in proxy.ts and masking.ts

3 weeks agoMerge pull request #8 from mkroemer/fix/multimodal-content-support
Stefan Gasser [Sat, 10 Jan 2026 13:23:29 +0000 (14:23 +0100)]
Merge pull request #8 from mkroemer/fix/multimodal-content-support

Fix/multimodal content support

3 weeks agoYou are right, and I (and claude) addressed these issues.
mkroemer [Sat, 10 Jan 2026 08:21:33 +0000 (09:21 +0100)]
You are right, and I (and claude) addressed these issues.

1. Secrets redaction (proxy.ts):
   - Add per-part offset tracking to prevent partial secret leaks
   - Filter and adjust redaction positions for each text part
   - Fixes issue where 'sk-proj-' prefix could remain visible

2. PII masking (masking.ts):
   - Actually mask array content instead of returning original
   - Add per-part offset tracking for accurate entity positions
   - Properly handle multimodal arrays with text and images

3. Tests:
   - Add content.test.ts for text extraction utilities
   - Add multimodal.test.ts with integration tests

3 weeks agofix: Update type system for multimodal content support
mkroemer [Fri, 9 Jan 2026 20:06:49 +0000 (21:06 +0100)]
fix: Update type system for multimodal content support

- Update ChatMessage interface to accept MessageContent type
- Fix masking.ts to handle multimodal content
- Fix redact.ts to extract text before processing
- Fix import order and formatting per biome linter

3 weeks agofix: Add support for multimodal content (text + images)
mkroemer [Fri, 9 Jan 2026 19:58:56 +0000 (20:58 +0100)]
fix: Add support for multimodal content (text + images)

Fixes crashes when processing OpenAI Chat Completion requests with
multimodal content (array format). Previously, the code assumed message
content is always a string, causing Presidio errors and 502/503 responses
when LibreChat Agents sent vision requests.

Changes:
- Add extractTextContent() utility to safely extract text from both
  string and array content formats
- Update PII detection to handle multimodal messages
- Update secrets detection to extract text from array content
- Update message redaction to preserve images while redacting text
- Fix dashboard display to show readable content instead of [object Object]

This enables full support for OpenAI's multimodal API format while
maintaining PII/secrets protection on text portions.

Resolves issues with LibreChat Agents feature returning 502 errors.

3 weeks agoMerge pull request #7 from maximiliancw/main
Stefan Gasser [Fri, 9 Jan 2026 17:26:03 +0000 (18:26 +0100)]
Merge pull request #7 from maximiliancw/main

Add secrets detection to prevent credential leaks

3 weeks agoRefine bearer token and JWT token detection patterns to enforce minimum character...
maximiliancw [Fri, 9 Jan 2026 16:10:15 +0000 (17:10 +0100)]
Refine bearer token and JWT token detection patterns to enforce minimum character requirements;
Updated tests to reflect changes in bearer token format

3 weeks agoUpdate all references to outdated versions
maximiliancw [Fri, 9 Jan 2026 16:03:55 +0000 (17:03 +0100)]
Update all references to outdated versions

3 weeks agoEnhance request logging to conditionally include detected secret types based on confi...
maximiliancw [Fri, 9 Jan 2026 16:00:19 +0000 (17:00 +0100)]
Enhance request logging to conditionally include detected secret types based on configuration; ensuring sensitive information is only logged when explicitly allowed, improving security and compliance

3 weeks agoClarify max_scan_chars behavior for secrets detection; Added notes on detection limit...
maximiliancw [Fri, 9 Jan 2026 15:57:49 +0000 (16:57 +0100)]
Clarify max_scan_chars behavior for secrets detection; Added notes on detection limits and performance implications

3 weeks agoFix: removed space in joined header string for consistency
maximiliancw [Fri, 9 Jan 2026 15:56:09 +0000 (16:56 +0100)]
Fix: removed space in joined header string for consistency

3 weeks agoUse OpenAI-compatible error format for secrets blocking:
maximiliancw [Fri, 9 Jan 2026 15:52:46 +0000 (16:52 +0100)]
Use OpenAI-compatible error format for secrets blocking:

- Use 400 status code instead of 422
- Use standard error format {message, type, param, code}
- Remove non-standard 'details' field (secret types already in headers)
- Update tests to match new format

3 weeks agoAdd database migration for secrets detection columns
maximiliancw [Fri, 9 Jan 2026 15:23:47 +0000 (16:23 +0100)]
Add database migration for secrets detection columns

Existing installations will fail with 'table request_logs has no column
named secrets_detected' since the new columns don't exist in their SQLite
database. This adds a migration check that adds the missing columns if they
don't exist.

3 weeks agoImplement redact and route_local actions:
maximiliancw [Fri, 9 Jan 2026 15:04:32 +0000 (16:04 +0100)]
Implement redact and route_local actions:

- Integrate redact action: redacts secrets before PII detection, unredacts in responses
- Implement route_local action: routes requests with secrets to local provider
- Update stream transformer to handle both PII and secrets contexts
- Add comprehensive tests for secrets routing logic
- Update config.example.yaml with new entity types and action documentation
- Update README.md with complete secrets detection features

New secret entity types (opt-in):

- API_KEY_OPENAI, API_KEY_AWS, API_KEY_GITHUB
- JWT_TOKEN, BEARER_TOKEN

Response headers:
- X-PasteGuard-Secrets-Redacted: true (when action=redact)

3 weeks agoAdd reversible redaction module for secret masking:
maximiliancw [Fri, 9 Jan 2026 15:02:22 +0000 (16:02 +0100)]
Add reversible redaction module for secret masking:

- Create redact.ts with RedactionContext for tracking secret mappings
- Implement redactSecrets() with configurable placeholder format
- Implement unredactSecrets() for restoring original secrets in responses
- Add streaming helpers for unredacting SSE responses
- Add comprehensive tests covering roundtrip, multiple messages, and streaming

3 weeks agofeat(secrets): add detection for API keys, JWT tokens, and Bearer tokens
maximiliancw [Fri, 9 Jan 2026 14:52:56 +0000 (15:52 +0100)]
feat(secrets): add detection for API keys, JWT tokens, and Bearer tokens

- Add new secret entity types: API_KEY_OPENAI, API_KEY_AWS, API_KEY_GITHUB, JWT_TOKEN, BEARER_TOKEN
- Extract pattern detection into reusable helper function
- Add comprehensive tests for all new secret types with false positive checks
- Update config schema with typed entity enum

3 weeks agoImprove error messaging for secrets detection configuration validation on startup
maximiliancw [Fri, 9 Jan 2026 14:38:08 +0000 (15:38 +0100)]
Improve error messaging for secrets detection configuration validation on startup

3 weeks agoMerge remote-tracking branch 'origin/main'
maximiliancw [Fri, 9 Jan 2026 14:24:41 +0000 (15:24 +0100)]
Merge remote-tracking branch 'origin/main'

# Conflicts:
# README.md
# src/routes/proxy.ts

3 weeks agoPrepare for merge with breaking changes from remote origin
maximiliancw [Fri, 9 Jan 2026 14:21:23 +0000 (15:21 +0100)]
Prepare for merge with breaking changes from remote origin

3 weeks agoAdd secrets shield feature documentation to README
maximiliancw [Fri, 9 Jan 2026 13:59:18 +0000 (14:59 +0100)]
Add secrets shield feature documentation to README

3 weeks agoAdd simple integration tests for secrets detection blocking behavior in proxy.ts
maximiliancw [Fri, 9 Jan 2026 13:55:10 +0000 (14:55 +0100)]
Add simple integration tests for secrets detection blocking behavior in proxy.ts

3 weeks agoAdd comprehensive unit tests for secrets detection
maximiliancw [Fri, 9 Jan 2026 13:52:51 +0000 (14:52 +0100)]
Add comprehensive unit tests for secrets detection

3 weeks agoAdd validation for secrets detection config on startup and update banner
maximiliancw [Fri, 9 Jan 2026 13:49:27 +0000 (14:49 +0100)]
Add validation for secrets detection config on startup and update banner

3 weeks agoEnhance secrets detection functionality in proxy routes:
maximiliancw [Fri, 9 Jan 2026 13:44:59 +0000 (14:44 +0100)]
Enhance secrets detection functionality in proxy routes:

- Integrate secrets detection logic into the proxy request handling.
- Add configuration checks for enabling/disabling secrets detection.
- Implement logging for detected secrets and their types.
- Update the logger to accommodate new fields for secrets detection.
- Refactor related functions for improved clarity and maintainability

3 weeks agoRename setShieldHeaders to setPasteGuardHeaders
Stefan Gasser [Fri, 9 Jan 2026 13:37:25 +0000 (14:37 +0100)]
Rename setShieldHeaders to setPasteGuardHeaders

3 weeks agoUpdate dashboard screenshot with PasteGuard branding (#6)
Stefan Gasser [Fri, 9 Jan 2026 13:27:51 +0000 (14:27 +0100)]
Update dashboard screenshot with PasteGuard branding (#6)

3 weeks agoExtend .gitignore
maximiliancw [Fri, 9 Jan 2026 13:02:05 +0000 (14:02 +0100)]
Extend .gitignore

3 weeks agoRename project from LLM-Shield to PasteGuard (#5)
Stefan Gasser [Fri, 9 Jan 2026 12:57:21 +0000 (13:57 +0100)]
Rename project from LLM-Shield to PasteGuard (#5)

After positive community response (100+ GitHub stars), committing fully
to this project. The name PasteGuard better describes the core function:
"guard what you paste" before sending to LLMs.

Changes:
- Update all branding: package.json, README, CONTRIBUTING
- Rename response headers: X-LLM-Shield-* → X-PasteGuard-*
- Update dashboard UI and page title
- Update /info endpoint metadata
- Update startup banner
- Update config files and defaults
- Update CI workflow docker tag
- Regenerate bun.lock with new package name

Domain pasteguard.com secured. Old GitHub links redirect automatically.

3 weeks agoAdd text extraction utility function
maximiliancw [Fri, 9 Jan 2026 12:55:01 +0000 (13:55 +0100)]
Add text extraction utility function

3 weeks agoImplement secrets detection module for OpenSSH and PEM private keys
maximiliancw [Fri, 9 Jan 2026 12:49:45 +0000 (13:49 +0100)]
Implement secrets detection module for OpenSSH and PEM private keys

3 weeks agoAdd secrets_detection section to config.example.yaml
maximiliancw [Fri, 9 Jan 2026 12:33:47 +0000 (13:33 +0100)]
Add secrets_detection section to config.example.yaml

3 weeks agoAdd secrets detection config schema with validation
maximiliancw [Fri, 9 Jan 2026 12:31:10 +0000 (13:31 +0100)]
Add secrets detection config schema with validation

3 weeks agoRename chat routes to proxy for clarity (#4)
Stefan Gasser [Fri, 9 Jan 2026 08:07:56 +0000 (09:07 +0100)]
Rename chat routes to proxy for clarity (#4)

- Rename chat.ts → proxy.ts to better reflect purpose (LLM proxy routing)
- Update CLAUDE.md architecture to match actual file structure

3 weeks agoFix EISDIR error when config.yaml is a directory (#3)
Stefan Gasser [Fri, 9 Jan 2026 07:28:55 +0000 (08:28 +0100)]
Fix EISDIR error when config.yaml is a directory (#3)

Add isFile() check before reading config to give a clear error message
when Docker creates a directory instead of mounting a missing file.

Fixes #2

3 weeks agoAdd PII accuracy benchmark with multi-language phone context (#1)
Stefan Gasser [Thu, 8 Jan 2026 16:15:59 +0000 (17:15 +0100)]
Add PII accuracy benchmark with multi-language phone context (#1)

- Add benchmark framework with precision/recall/F1 metrics
- Add 30 test cases across 5 languages (DE, EN, ES, FR, IT)
- Add phone_context words for all 24 supported languages
- Each language has 5-7 native words for: phone, number, mobile, call

Test with: bun run benchmark:accuracy

3 weeks agofix: support environment variables in numeric config values
Stefan Gasser [Thu, 8 Jan 2026 11:15:42 +0000 (12:15 +0100)]
fix: support environment variables in numeric config values

Use z.coerce.number() to handle string values from environment variable
substitution in YAML config. Add validation constraints:

- port: integer 1-65535
- retention_days: integer >= 0
- score_threshold: float 0-1

3 weeks agoInitial release
Stefan Gasser [Thu, 8 Jan 2026 10:14:12 +0000 (11:14 +0100)]
Initial release

OpenAI-compatible privacy proxy with two modes:
- Mask: Replace PII with placeholders before upstream, unmask in response
- Route: Send PII-containing requests to local LLM

Features:
- 24 language support for PII detection
- Real-time streaming with unmasking
- Dashboard for monitoring
- Microsoft Presidio integration

git clone https://git.99rst.org/PROJECT