Skip to content
Founders$49 once → 2 years of Pro ($98 value)Become Founder →
ClauLock

Security

The never-reveal invariant.

ClauLock's central guarantee is structural, not probabilistic: the Claude model never receives the plaintext value of a stored secret. The MCP surface is shaped so that no tool, under any input, returns a raw value. Enforcement happens at the socket, not in a prompt.

"Probabilistic" means a model could be talked into leaking under the right adversarial prompt. "Structural" means the leak path doesn't exist — there's no API call that returns a plaintext value to the model, regardless of how the model is prompted.

What ClauLock protects against

  • Transcript leaks. Shell commands referencing {{NAME}} are rewritten at the PreToolUse hook to run under clsec-exec; the placeholder stays in the transcript and the value is substituted at fork/exec.
  • Exfil via MCP. The MCP server runs under role Mcp, which the daemon blocks from calling Method::Resolve. A compromised MCP binary still cannot ask for a value.
  • Memory scraping. DEKs and the KEK live in mlocked pages and are zeroed on drop. Anti-debugger hardening (PT_DENY_ATTACH) is on the upcoming roadmap; for now ClauLock assumes an uncompromised user session.
  • Socket spoofing. The daemon binds a 0600 Unix socket in the user's runtime directory and verifies callers via SO_PEERCRED (Linux) / LOCAL_PEERPID (macOS), matching the peer binary against an allowlist.
  • Record-swap attacks. Each record is encrypted with the record id as AAD, so an attacker with write access to the vault cannot splice a ciphertext under a different name.

What ClauLock does not protect against

  • A fully compromised endpoint. Root-level malware with access to your kernel, your process memory, or your keyboard can always win. ClauLock raises the cost, not to infinity.
  • User-initiated leaks. If you ask Claude to "print my GitHub token," ClauLock will not hand it over — but if you paste it into chat yourself, the transcript will contain it. We can't protect you from you.
  • Remote services misusing secrets. Once curl sends your token to GitHub, GitHub has it. ClauLock is not a policy engine for upstream APIs.
  • Swap / hibernation leaks. mlock prevents paging of the daemon's sensitive pages; we still recommend encrypted swap.

Cryptographic details

passphrase  (macOS Keychain / freedesktop secret-service)
    ↓  Argon2id (m = 256 MiB, t = 3, p = 4)
KEK         (32 bytes)
    ↓  XChaCha20-Poly1305 wrap
DEK₁        (32 bytes, random, per record)
    ↓  XChaCha20-Poly1305  (AAD = record_id)
ciphertext₁
  • AEAD: XChaCha20-Poly1305, 24-byte random nonces, record id bound as AAD.
  • KDF: Argon2id with the OWASP parameters above; tuning knobs exposed for enterprise builds.
  • Rotation: rotating the passphrase re-wraps DEKs but does not re-encrypt every secret. Rotating a secret generates a fresh DEK and preserves id and created_at.
  • Vault format: append-only, atomically swapped on write, portable across machines when paired with the passphrase.

Roles and access control

Role Binary Can call Resolve?
Cli clsec, clsec-exec Yes
Mcp clsec-mcp No — blocked at the daemon
Ui Companion app (planned) Yes, with biometric approval

The Companion UI exception

The Companion UI is the only ClauLock surface that can show a secret's plaintext value, and only after a fresh Touch ID prompt for that specific reveal. This is a deliberate exception that respects the invariant: the Claude model still cannot pull the value through any path — the daemon's role gate denies Method::Reveal for every caller except CallerRole::Ui, and denies Method::Resolve for Mcp and Ui.

  • Ephemeral display. The value renders in the UI for 15 seconds and auto-hides. No shell history, no scrollback, no pager. Clipboard copies auto-clear after 20 seconds.
  • Per-action biometric. Vault-unlocked-an-hour-ago is not sufficient. Every reveal re-prompts Touch ID. Linux uses polkit (planned). Windows Hello support tracks the next Windows release.
  • Attributable. Every reveal lands in the audit log with tool=reveal, outcome=ok|denied — visible via clsec audit or in the UI's own audit timeline.
  • Out of scope: a compromised local user session. If an attacker controls the logged-in account, they can pass Touch ID with the user's finger or shoulder-surf the 15-second window. ClauLock is not a Yubikey replacement; it's an agent-context boundary. See docs/ui-reveal.md for the full trust-boundary diagram and protocol details.

Audit log

Every Add, Resolve, Rotate, and Delete is recorded with timestamp, caller PID, caller binary path, and result. Read it from the CLI:

clsec audit --limit 50

Reporting a vulnerability

Email [email protected] — do not open a public issue. We acknowledge within 48 hours and target a fix within 30 days for high-severity findings. Full policy and bounty tiers in SECURITY.md.