¿Qué hace signed-audit-trails-recipe?
Guía paso a paso para configurar registros de auditoría con firma criptográfica en las llamadas a herramientas de Claude Code. Útil para explicar, evaluar o demostrar el patrón antes de comprometerse con los hooks de ejecución de protect-mcp. Cubre políticas Cedar, recibos Ed25519, verificación fuera de línea, detección de manipulación, integración CI/CD y composición SLSA.
Prerrequisitos
- Claude Code instalado y configurado
- Acceso a herramientas de línea de comandos (bash)
- Node.js v18+ (para el ejemplo de verificación)
- OpenSSL (para generación de claves)
Descripción General
Este recetario implementa un sistema de registros de auditoría firmados que permite:
- Firmar cada llamada a herramienta con una clave privada Ed25519
- Verificar la autenticidad de los registros fuera de línea
- Detectar manipulaciones en los registros almacenados
- Integrar con políticas Cedar para control de acceso
- Componer con SLSA para garantizar la procedencia del software
Pasos
1. Generar Claves
openssl genpkey -algorithm ed25519 -out private_key.pem
openssl pkey -in private_key.pem -pubout -out public_key.pem
2. Configurar el Hook de Claude Code
Crea un archivo ~/.claude/hooks/audit.js:
const { execSync } = require('child_process');
const crypto = require('crypto');
module.exports = async (toolCall) => {
const receipt = {
tool: toolCall.name,
input: toolCall.input,
timestamp: new Date().toISOString(),
nonce: crypto.randomUUID()
};
// Firmar con clave privada
const sign = crypto.createSign('ed25519');
sign.update(JSON.stringify(receipt));
receipt.signature = sign.sign(execSync('cat private_key.pem'), 'hex');
// Almacenar en archivo de auditoría
const fs = require('fs');
fs.appendFileSync('audit.log', JSON.stringify(receipt) + '\n');
return receipt;
};
3. Verificación Fuera de Línea
# Script de verificación (verify.sh)
#!/bin/bash
while IFS= read -r line; do
echo "$line" | node -e "
const fs = require('fs');
const crypto = require('crypto');
const data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
const signature = Buffer.from(data.signature, 'hex');
const pubKey = fs.readFileSync('public_key.pem');
const verify = crypto.createVerify('ed25519');
delete data.signature;
verify.update(JSON.stringify(data));
console.log(verify.verify(pubKey, signature) ? 'VÁLIDO' : 'INVÁLIDO');
"
done < audit.log
4. Política Cedar (Opcional)
Define una política Cedar básica (policy.cedar):
permit(
principal,
action in ["tool::read", "tool::write"],
resource
)
when {
context.audit_signature != null &&
context.timestamp > 1700000000
};
5. Integración CI/CD
Agrega un paso en tu pipeline (GitHub Actions, GitLab CI, etc.):
- name: Verificar registros de auditoría
run: |
bash verify.sh audit.log
if [ $? -ne 0 ]; then
echo "Registros de auditoría inválidos o manipulados"
exit 1
fi
6. Composición SLSA
Para cumplir con SLSA, asegúrate de:
- Los registros se generan en un entorno aislado
- Las claves privadas nunca se almacenan en repositorios
- Los registros se firman antes de cualquier transmisión
- Se mantiene una cadena de firmas (cada registro referencia al anterior)
Recursos Adicionales
Notas
- Ajusta las rutas de archivos según tu sistema operativo
- En Windows, utiliza
typeen lugar decat - Considera rotar las claves periódicamente
- Para entornos de producción, usa un gestor de secretos como Vault