Seguridad
El invariante never-reveal.
La garantía central de ClauLock es estructural, no probabilística: el modelo Claude nunca recibe el valor en texto plano de un secreto almacenado. La superficie MCP está construida de forma que ninguna tool, bajo ningún input, devuelve un valor crudo. El enforcement ocurre en el socket, no en un prompt.
"Probabilística" significa que un modelo podría ser convencido de leakear bajo el prompt adversarial correcto. "Estructural" significa que el camino de leak no existe — no hay llamada API que devuelva un valor en texto plano al modelo, sin importar cómo se le pida.
Contra qué protege ClauLock
- Leaks al transcript.
Los comandos shell que referencian
{{NAME}}se reescriben en el hook PreToolUse para correr bajoclsec-exec; el placeholder se queda en el transcript y el valor se sustituye enfork/exec. - Exfil vía MCP. El servidor
MCP corre bajo el rol
Mcp, que el daemon bloquea de llamarMethod::Resolve. Un binario MCP comprometido sigue sin poder pedir un valor. - Memory scraping. Las DEKs y
la KEK viven en páginas
mlocked y se ponen a cero al hacer drop. Un pasePT_DENY_ATTACHestá planeado para el release v0.1. - Spoofing del socket. El
daemon vincula un socket Unix
0600en el directorio runtime del usuario y verifica a los callers víaSO_PEERCRED(Linux) /LOCAL_PEERPID(macOS), comparando el binario peer contra un allowlist. - Ataques record-swap. Cada record se cifra con el id del record como AAD, así un atacante con acceso de escritura al vault no puede empalmar un ciphertext bajo un nombre distinto.
Contra qué ClauLock no protege
- Un endpoint totalmente comprometido. Malware con acceso de root a tu kernel, a la memoria de tu proceso o a tu teclado siempre puede ganar. ClauLock eleva el costo, no al infinito.
- Leaks iniciados por el usuario. Si le pides a Claude "imprime mi token de GitHub", ClauLock no se lo entregará — pero si tú mismo lo pegas en el chat, el transcript lo contendrá. No podemos protegerte de ti.
- Servicios remotos mal usando secretos.
Una vez que
curlmanda tu token a GitHub, GitHub lo tiene. ClauLock no es un policy engine para APIs upstream. - Leaks por swap / hibernación.
mlockpreviene el paging de las páginas sensibles del daemon; igual recomendamos swap cifrado.
Detalles criptográficos
passphrase (Keychain macOS / freedesktop secret-service)
↓ Argon2id (m = 256 MiB, t = 3, p = 4)
KEK (32 bytes)
↓ wrap XChaCha20-Poly1305
DEK₁ (32 bytes, aleatoria, por record)
↓ XChaCha20-Poly1305 (AAD = record_id)
ciphertext₁ - AEAD: XChaCha20-Poly1305, nonces aleatorios de 24 bytes, id de record atado como AAD.
- KDF: Argon2id con los parámetros OWASP de arriba; knobs de tuning expuestos para builds enterprise.
- Rotación: rotar la passphrase
re-envuelve las DEKs pero no re-cifra cada secreto. Rotar un
secreto genera una DEK fresca y preserva
idycreated_at. - Formato del vault: append-only, swap atómico en write, portable entre máquinas cuando se empareja con la passphrase.
Roles y control de acceso
| Rol | Binario | ¿Puede llamar Resolve? |
|---|---|---|
Cli | clsec, clsec-exec | Sí |
Mcp | clsec-mcp | No — bloqueado en el daemon |
Ui | App companion (planeado) | Sí, con aprobación biométrica |
La excepción de la Companion UI
La Companion UI es la única
superficie de ClauLock que puede mostrar el valor en texto
plano de un secreto, y solo tras un prompt fresco de Touch ID
para esa revelación específica. Es una excepción deliberada
que respeta el invariante: el modelo Claude sigue sin poder
obtener el valor por ninguna ruta — el role gate del daemon
rechaza Method::Reveal para
cualquier caller excepto CallerRole::Ui,
y rechaza Method::Resolve para
Mcp y Ui.
- Display efímero. El valor se renderea en la UI por 15 segundos y se auto-oculta. Sin shell history, sin scrollback, sin pager. Las copias al clipboard se auto-limpian tras 20 segundos.
- Biométrico por acción.
"Vault desbloqueado hace una hora" no es suficiente. Cada
reveal re-prompea Touch ID. Linux usa
polkit(planeado). Windows Hello track v0.2. - Atribuible. Cada
reveal aterriza en el audit log con
tool=reveal, outcome=ok|denied— visible víaclsec audito en el timeline de auditoría de la UI. - Fuera de scope: una sesión de usuario local comprometida. Si un atacante controla la cuenta logueada, puede pasar Touch ID con tu dedo o ver la ventana de 15 segundos. ClauLock no es un reemplazo de Yubikey; es un boundary de contexto-de-agente. Ver docs/ui-reveal.md para el diagrama completo de trust boundary y detalles del protocolo.
Audit log
Cada Add,
Resolve,
Rotate y
Delete queda registrado con
timestamp, PID del caller, path del binario caller y resultado.
Léelo desde la CLI:
clsec audit --limit 50 Reportar una vulnerabilidad
Email a [email protected] — no abras un issue público. Confirmamos en 48 horas y apuntamos a un fix en 30 días para hallazgos de severidad alta. Política completa y tiers de bounty en SECURITY.md.