Skip to main content

Documentation Index

Fetch the complete documentation index at: https://woku.app/docs/llms.txt

Use this file to discover all available pages before exploring further.

Woku usa dos primitivas criptográficas para proteger los datos que guarda en su base:
  • Cifrado AES-256-GCM para campos sensibles en reposo.
  • HMAC-SHA256 para firmar documentos críticos y detectar cualquier modificación posterior.
Ambas primitivas viven en un único EncryptionService del backend y usan la misma clave maestra (ENCRYPTION_KEY) derivada vía scrypt.

Cifrado en reposo

Cuándo se cifra

Todo campo que contenga información personal o credenciales se cifra antes de persistirse en MongoDB. En particular:
  • Datos de cliente en respuestas anónimas: email y teléfono se almacenan cifrados (form-submission).
  • Credenciales de integraciones y tokens de OAuth (cuando una empresa conecta Woku con Salesforce, Sperant, etc.).
  • Secrets de webhooks que la empresa configura para recibir eventos.

Cómo funciona

Valor
AlgoritmoAES-256-GCM (autenticación integrada vía auth tag)
LlaveDerivada con scrypt(ENCRYPTION_KEY, salt, 32)
IVAleatorio de 12 bytes por cada cifrado
Formato persistido<iv-hex>:<authTag-hex>:<ciphertext-hex>
Cada cifrado usa un IV nuevo, así que cifrar dos veces el mismo valor produce dos ciphertexts distintos (no se puede inferir igualdad por inspección). El authTag se valida en cada descifrado: si el ciphertext fue alterado, el descifrado lanza un error en vez de devolver basura.

Búsqueda sobre campos cifrados

Para poder buscar por email sin descifrar todos los registros, Woku guarda un hash SHA-256 paralelo (generateSearchHash) en lowercase. La búsqueda compara hash contra hash, no texto contra texto.

Firmas de integridad (HMAC-SHA256)

Para qué sirven

Cuando una empresa exige que sus respuestas de formularios no puedan ser modificadas después de almacenarse (auditoría legal, compliance de sector regulado), Woku puede firmar cada documento con HMAC-SHA256 al momento de escribirlo y verificar la firma al leerlo. Si alguien modifica el documento en la base directamente, la verificación falla y la lectura devuelve error.

Cómo funciona

firma = HMAC-SHA256(ENCRYPTION_KEY, "<scope>:<json canonical del doc>")
Detalle
AlgoritmoHMAC-SHA256
LlaveLa misma ENCRYPTION_KEY derivada arriba
EntradaConcatenación <scope>:<json>
Salida64 caracteres hex
VerificaciónConstant-time (crypto.timingSafeEqual)
Scope = separación de dominio: cada caso de uso firma con un scope distinto (ej: form-submission, form-response). Una firma generada para un scope no es válida en otro, así un atacante no puede mover firmas entre tipos de documentos. JSON canónico: Woku ordena recursivamente las llaves de los objetos antes de firmar, así dos representaciones lógicamente iguales del mismo documento producen la misma firma (independiente de en qué orden las recibió la API o las escribió Mongo). Los arrays NO se reordenan, el orden posicional es semánticamente significativo.

Activar para tu empresa

Hay un flag por empresa: integrityHashEnabled. Cuando se activa, las nuevas escrituras de documentos críticos se firman; las lecturas verifican y fallan si la firma no coincide.
Estado actual: la primitiva (signDocument / verifySignature) ya está disponible en el backend y el flag existe en el modelo de empresa. La integración automática con form-submission y form-response (cuando integrityHashEnabled está activo) llega en un release posterior. Los clientes con compliance estricto que necesiten esto antes pueden coordinarlo con soporte.

Gestión de llave

  • ENCRYPTION_KEY vive en SSM Parameter Store como SecureString bajo /shared/prod/secrets/ENCRYPTION_KEY y se inyecta al container al arrancar (ver Gestión de secrets).
  • Rotación de la llave es manual hoy. Implica:
    1. Generar la llave nueva.
    2. Re-cifrar todos los registros (script de migración) con la nueva llave antes de switchear ENCRYPTION_KEY en SSM, en una ventana de mantenimiento.
    3. Descartar la vieja.
  • No hay HSM en V1; la llave vive en variables de entorno del proceso (en memoria) y nunca se loggea.

Garantías

  • Cifrado autenticado: si un atacante modifica el ciphertext en la base, el authTag no valida y el descifrado lanza error → el registro alterado no se devuelve como si fuera válido.
  • Firma constant-time: verifySignature usa comparación resistente a timing attacks.
  • Domain separation: el scope en HMAC evita reutilización de firmas entre tipos de documentos.
  • JSON determinístico: la canonicalización elimina ambigüedad por orden de llaves.

Limitaciones conocidas

  • La rotación de ENCRYPTION_KEY requiere ventana de mantenimiento (no hay key versioning aún).
  • La firma de form-submission / form-response no está cableada automáticamente; llega en el release de Stage 10.
  • La aplicación a credenciales de integraciones de terceros depende de que esas integraciones se construyan (Stage 6).