🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
15 KiB
Plan: Hybrid Secret Detection with Sanitized Log Replication
1. Objective
To implement a robust, two-stage secret detection pipeline that:
- Reads from a primary hypercore log in real-time.
- Uses a fast, regex-based scanner for initial detection.
- Leverages a local LLM (via Ollama) for deeper, context-aware analysis of potential secrets to reduce false positives.
- Writes a fully sanitized version of the log to a new, parallel "sister" hypercore stream.
- Quarantines and alerts on confirmed high-severity secrets, ensuring the original log remains untouched for audit purposes while the sanitized log is safe for wider consumption.
2. High-Level Architecture & Data Flow
The process will follow this data flow:
┌──────────────────────────┐
[Primary Hypercore Log] ─────► │ HypercoreReader │
└────────────┬─────────────┘
│ (Raw Log Entry)
▼
┌──────────<E29480><E29480>───────────────┐
│ MessageProcessor │
│ (Orchestrator) │
└────────────┬─────────────┘
│
┌───────────────────────▼───────────────────────┐
│ Stage 1: Fast Regex Scan │
│ (SecretDetector) │
└───────────────────────┬───────────────────────┘
│
┌───────────────────────────┼───────────────────────────┐
│ (No Match) │ (Potential Match) │ (High-Confidence Match)
▼ ▼ ▼
┌──────────────────────────┐ ┌─<E2948C><E29480>────────────────────────┐ ┌──────────────────────────┐
│ SanitizedWriter │ │ Stage 2: LLM Analysis │ │ (Skip LLM) │
│ (Writes original entry) │ │ (LLMAnalyzer) │ │ Quarantine Immediately │
└──────────────────────────┘ └────────────┬─────────────┘ └────────────┬─────────────┘
▲ │ (LLM Confirms) │
│ ▼ ▼
│ ┌──────────────────────────┐ ┌──────────────────────────┐
│ │ QuarantineManager │ │ Alerting System │
│ │ (DB Storage, Alerts) │ │ (Webhooks) │
│ └──────────────────────────┘ └────────────<E29480><E29480>─────────────┘
│ │
│ ▼
│ ┌──────────────────────────┐
└──────────────┤ SanitizedWriter │
│ (Writes REDACTED entry) │
└──────────────────────────┘
│
▼
[Sanitized Hypercore Log]
3. Component Implementation Plan
This plan modifies existing components and adds new ones.
3.1. New Component: core/llm_analyzer.py
This new file will contain all logic for interacting with the Ollama instance. This isolates the dependency and makes it easy to test or swap out the LLM backend.
# core/llm_analyzer.py
import requests
import json
class LLMAnalyzer:
"""Analyzes text for secrets using a local LLM via Ollama."""
def __init__(self, endpoint: str, model: str, system_prompt: str):
self.endpoint = endpoint
self.model = model
self.system_prompt = system_prompt
def analyze(self, text: str) -> dict:
"""
Sends text to the Ollama API for analysis and returns a structured JSON response.
Returns:
A dictionary like:
{
"secret_found": bool,
"secret_type": str,
"confidence_score": float,
"severity": str
}
Returns a default "not found" response on error.
"""
prompt = f"Log entry: \"{text}\"\n\nAnalyze this for secrets and respond with only the required JSON."
payload = {
"model": self.model,
"system": self.system_prompt,
"prompt": prompt,
"format": "json",
"stream": False
}
try:
response = requests.post(self.endpoint, json=payload, timeout=15)
response.raise_for_status()
# The response from Ollama is a JSON string, which needs to be parsed.
analysis = json.loads(response.json().get("response", "{}"))
return analysis
except (requests.exceptions.RequestException, json.JSONDecodeError) as e:
print(f"[ERROR] LLMAnalyzer failed: {e}")
# Fallback: If LLM fails, assume no secret was found to avoid blocking the pipeline.
return {"secret_found": False}
3.2. New Component: core/sanitized_writer.py
This component is responsible for writing to the new, sanitized hypercore log. This abstraction allows us to easily change the output destination in the future.
# core/sanitized_writer.py
class SanitizedWriter:
"""Writes log entries to the sanitized sister hypercore log."""
def __init__(self, sanitized_log_path: str):
self.log_path = sanitized_log_path
# Placeholder for hypercore writing logic. For now, we'll append to a file.
self.log_file = open(self.log_path, "a")
def write(self, log_entry: str):
"""Writes a single log entry to the sanitized stream."""
self.log_file.write(log_entry + "\n")
self.log_file.flush()
def close(self):
self.log_file.close()
3.3. Modify: core/detector.py
We will enhance the SecretDetector to not only find matches but also redact them.
# core/detector.py
import re
class SecretDetector:
def __init__(self, patterns_file: str = "patterns.yaml"):
# ... (load_patterns remains the same) ...
def scan(self, text: str) -> list[dict]:
"""Scans text and returns a list of found secrets with metadata."""
matches = []
for pattern_name, pattern in self.patterns.items():
if pattern.get("active", True):
regex_match = re.search(pattern["regex"], text)
if regex_match:
matches.append({
"secret_type": pattern_name,
"value": regex_match.group(0),
"confidence": pattern.get("confidence", 0.8), # Default confidence
"severity": pattern.get("severity", "MEDIUM")
})
return matches
def redact(self, text: str, secret_value: str) -> str:
"""Redacts a specific secret value within a string."""
redacted_str = secret_value[:4] + "****" + secret_value[-4:]
return text.replace(secret_value, f"[REDACTED:{redacted_str}]")
3.4. Modify: pipeline/processor.py
This is the orchestrator and will see the most significant changes to implement the hybrid logic.
# pipeline/processor.py
from core.hypercore_reader import HypercoreReader
from core.detector import SecretDetector
from core.llm_analyzer import LLMAnalyzer
from core.quarantine import QuarantineManager
from core.sanitized_writer import SanitizedWriter
class MessageProcessor:
def __init__(self, reader: HypercoreReader, detector: SecretDetector, llm_analyzer: LLMAnalyzer, quarantine: QuarantineManager, writer: SanitizedWriter, llm_threshold: float):
self.reader = reader
self.detector = detector
self.llm_analyzer = llm_analyzer
self.quarantine = quarantine
self.writer = writer
self.llm_threshold = llm_threshold # e.g., 0.90
async def process_stream(self):
"""Main processing loop for the hybrid detection model."""
async for entry in self.reader.stream_entries():
# Stage 1: Fast Regex Scan
regex_matches = self.detector.scan(entry.content)
if not regex_matches:
# No secrets found, write original entry to sanitized log
self.writer.write(entry.content)
continue
# A potential secret was found. Default to sanitized, but may be quarantined.
sanitized_content = entry.content
should_quarantine = False
confirmed_secret = None
for match in regex_matches:
# High-confidence regex matches trigger immediate quarantine, skipping LLM.
if match['confidence'] >= self.llm_threshold:
should_quarantine = True
confirmed_secret = match
break # One high-confidence match is enough
# Stage 2: Low-confidence matches go to LLM for verification.
llm_result = self.llm_analyzer.analyze(entry.content)
if llm_result.get("secret_found"):
should_quarantine = True
# Prefer LLM's classification but use regex value for redaction
confirmed_secret = {
"secret_type": llm_result.get("secret_type", match['secret_type']),
"value": match['value'],
"severity": llm_result.get("severity", match['severity'])
}
break
if should_quarantine and confirmed_secret:
# A secret is confirmed. Redact, quarantine, and alert.
sanitized_content = self.detector.redact(entry.content, confirmed_secret['value'])
self.quarantine.quarantine_message(
message=entry,
secret_type=confirmed_secret['secret_type'],
severity=confirmed_secret['severity'],
redacted_content=sanitized_content
)
# Potentially trigger alerts here as well
print(f"[ALERT] Confirmed secret {confirmed_secret['secret_type']} found and quarantined.")
# Write the (potentially redacted) content to the sanitized log
self.writer.write(sanitized_content)
3.5. Modify: main.py
The main entry point will be updated to instantiate and wire together the new and modified components.
# main.py
# ... imports ...
import asyncio
from core.hypercore_reader import HypercoreReader
from core.detector import SecretDetector
from core.llm_analyzer import LLMAnalyzer
from core.quarantine import QuarantineManager
from core.sanitized_writer import SanitizedWriter
# ... other imports
def main():
# 1. Configuration
# Load from a new config.yaml or environment variables
PRIMARY_LOG_PATH = "/path/to/primary/hypercore.log"
SANITIZED_LOG_PATH = "/path/to/sanitized/hypercore.log"
PATTERNS_PATH = "patterns.yaml"
DB_CONNECTION = "..."
OLLAMA_ENDPOINT = "http://localhost:11434/api/generate"
OLLAMA_MODEL = "llama3"
LLM_CONFIDENCE_THRESHOLD = 0.90 # Regex confidence >= this skips LLM
with open("SHHH_SECRETS_SENTINEL_AGENT_PROMPT.md", "r") as f:
OLLAMA_SYSTEM_PROMPT = f.read()
# 2. Instantiation
reader = HypercoreReader(PRIMARY_LOG_PATH)
detector = SecretDetector(PATTERNS_PATH)
llm_analyzer = LLMAnalyzer(OLLAMA_ENDPOINT, OLLAMA_MODEL, OLLAMA_SYSTEM_PROMPT)
quarantine = QuarantineManager(DB_CONNECTION)
writer = SanitizedWriter(SANITIZED_LOG_PATH)
processor = MessageProcessor(
reader=reader,
detector=detector,
llm_analyzer=llm_analyzer,
quarantine=quarantine,
writer=writer,
llm_threshold=LLM_CONFIDENCE_THRESHOLD
)
# 3. Execution
print("Starting SHHH Hypercore Monitor...")
try:
asyncio.run(processor.process_stream())
except KeyboardInterrupt:
print("Shutting down...")
finally:
writer.close()
if __name__ == "__main__":
main()
4. Phased Rollout
-
Phase 1: Component Implementation (1-2 days)
- Create
core/llm_analyzer.pyandcore/sanitized_writer.py. - Write unit tests for both new components. Mock the
requestscalls for the analyzer. - Update
core/detector.pywith theredactmethod and update its unit tests.
- Create
-
Phase 2: Orchestration Logic (2-3 days)
- Implement the new logic in
pipeline/processor.py. - Write integration tests for the processor that simulate the full flow: no match, low-confidence match (with mocked LLM response), and high-confidence match.
- Update
main.pyto wire everything together.
- Implement the new logic in
-
Phase 3: Configuration & Testing (1 day)
- Add a
config.yamlto manage all paths, thresholds, and endpoints. - Perform an end-to-end test run with a sample log file and a running Ollama instance.
- Verify that the primary log is untouched, the sanitized log is created correctly (with and without redactions), and the quarantine database is populated as expected.
- Add a
5. Success Criteria
- Zero Leaks: The sanitized log stream contains no secrets.
- High Accuracy: False positive rate is demonstrably lower than a regex-only solution, verified during testing.
- Performance: The pipeline maintains acceptable latency (<200ms per log entry on average, accounting for occasional LLM analysis).
- Auditability: The primary log remains a perfect, unaltered source of truth. All detection and quarantine events are logged in the PostgreSQL database.