Cifrado de credenciales
Descripción
Cifrado de credenciales es la práctica de almacenar de forma segura las credenciales de acceso a sistemas externos (APIs, bases de datos, servicios SaaS) usando cifrado simétrico. En CreaRack Pro, toda credencial guardada en la base de datos se cifra con una clave dedicada que viaja en variables de entorno.
Principios
- Never plaintext in DB: Ninguna credencial (password, token, secret) se almacena en texto plano
- Symmetric encryption: Se usa Fernet (AES-128-CBC + HMAC-SHA256) con una clave compartida en tiempo de ejecución
- Single decryption point: Todo descifrado pasa por
CredentialManager, facilitando auditoría y rotación - Environment isolation: La clave de cifrado es una variable de entorno, no hardcodeada
Implementación en CreaRack Pro
Modelo
class Credential(models.Model):
# usuario, contraseña, token, etc. — almacenados en 'encrypted_value' como ciphertext
encrypted_value = models.BinaryField()
Manager (core/security/credential_manager.py)
encrypt_credential(plaintext)→ ciphertextdecrypt_credential(ciphertext)→ plaintext (intenta múltiples claves)
Cadena de descifrado
CREDENTIAL_ENCRYPTION_KEY (activa)
↓ (si falla)
CREDENTIAL_ENCRYPTION_KEY_OLD (si hay rotación)
↓ (si falla)
SECRET_KEY (legacy, fallback)
↓ (si falla)
DEV_KEY (rescue, solo dev)
Claves en uso
| Variable | Propósito | Ejemplo fuente |
|---|---|---|
CREDENTIAL_ENCRYPTION_KEY | Clave activa, la que cifra nuevos valores | Dokploy env, generada con secrets.token_hex(32) |
CREDENTIAL_ENCRYPTION_KEY_OLD | Clave anterior, solo descifra durante rotación | Vacía o la clave vieja durante transición |
SECRET_KEY | Fallback para compatibilidad | Django secret_key |
DEV_KEY | Constante de rescate en desarrollo | Hardcoded en código |
Seguridad de las claves
- Generación: RNG seguro (
secrets.*), idealmente fuera de sesiones interactivas que dejan transcript - Almacenamiento: Variables de entorno del orquestador (Dokploy, Kubernetes, etc.), nunca en
.envcommitteado - Acceso: Solo el proceso web + worker la leen al iniciar; no se expone en logs
- Rotación: Soportada mediante [[concept—security—key-rotation]], [[feature—security—credential-key-rotation]]
Auditoría
- Toda credencial se descifra bajo demanda (no en caché)
SystemLogregistra cuándo se accedió a una credencial- No se loguea el contenido (plaintext), solo el acceso
Antipatrones detectados
- ❌ Almacenar credenciales en
secretsJSON plaintext dentro de la DB - ❌ Usar
SECRET_KEYde Django como clave única de cifrado (debería ser fallback) - ❌ Generar claves en consola interactiva (quedan en transcript)
- ❌ No rotar claves cuando se sospecha exposición
Véase también
- [[feature—security—credential-key-rotation]]
- [[concept—security—key-rotation]]
- [[entity—core—service—credential-manager]]
- [[entity—core—config—credential-encryption-key-old]]