Conceptoactivecreado Mon Jun 01#security#cryptography#credential-management#encryption#best-practices#compliance#django
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]]
Referenciado desde
- CREDENTIAL_ENCRYPTION_KEY_OLD (variable de configuración)
- Endpoint: POST /api/agent/register-local-token (Agent deposita token local cifrado)
- Feature: Autenticación local del Agent — Fase 1 (Backend inerte)
- IP real del visitante a prueba de Cloudflare (v1.45.13)
- Rotación de Clave de Cifrado de Credenciales
- Rotación de claves (seguridad)
- Rotación de claves de cifrado de credenciales
- T1 Cifrado de Credenciales SNMP en Reposo