CREDENTIAL_ENCRYPTION_KEY_OLD (variable de configuración)
Descripción
Variable de entorno que aloja la clave de cifrado anterior durante un ciclo de rotación de credenciales. Solo se lee en la cadena de descifrado; nunca se usa para cifrar nuevos valores.
Estado: Vacía ("") cuando no hay rotación en curso.
Ubicación
- Definición:
config/settings/base.py(línea ~39) - Lectura:
core/security/credential_manager.py, método_decryption_chain()
CREDENTIAL_ENCRYPTION_KEY_OLD = os.getenv("CREDENTIAL_ENCRYPTION_KEY_OLD", "")
Propagación en entornos
Production (compose.prod.yml)
services:
web:
environment:
- CREDENTIAL_ENCRYPTION_KEY_OLD=${CREDENTIAL_ENCRYPTION_KEY_OLD:-}
worker:
environment:
- CREDENTIAL_ENCRYPTION_KEY_OLD=${CREDENTIAL_ENCRYPTION_KEY_OLD:-}
Development (compose.yml)
services:
web:
environment:
- CREDENTIAL_ENCRYPTION_KEY_OLD=${CREDENTIAL_ENCRYPTION_KEY_OLD:-}
Ciclo de vida en rotación
- Antes de rotación: Vacía (
"") - Inicia rotación: Se establece en Dokploy/orquestador a la clave antigua
- Se ejecuta
reencrypt_credentials: Migra todo ciphertext a la nueva clave - Se limpia: Se borra de entorno; la app no la lee más
- Después de rotación: Nuevamente vacía
Uso en descifrado
En core/security/credential_manager.py, la cadena de intento es:
def _decryption_chain(cls, include_dev_rescue=True):
chain = []
def _add(material):
if material and material not in chain:
chain.append(material)
_add(cls._active_key_material()) # CREDENTIAL_ENCRYPTION_KEY
_add((getattr(settings, "CREDENTIAL_ENCRYPTION_KEY_OLD", "") or "").strip() or None) # OLD
_add(getattr(settings, "SECRET_KEY", None)) # legacy
if include_dev_rescue:
_add(cls.DEV_KEY) # rescue
return chain
Si la variable está vacía o whitespace, se omite de la cadena.
Seguridad
- Secreto de entorno: Nunca se debe serializar, loguear o exponer
- Solo lectura en descifrado: El encriptado siempre usa
CREDENTIAL_ENCRYPTION_KEY(activa) - Limpieza obligatoria: Debe borrarse después de
reencrypt_credentialspara no mantener claves antiguas innecesariamente - Auditar antes de limpiar: Verificar que la migración fue completa y exitosa
Test
Validado en tests/test_credential_key_rotation.py::test_rotation_via_old_key:
- Verifica que ciphertext antiguo se descifra vía OLD cuando es activa la nueva clave
- Valida que nuevos ciphertexts se cifran con la clave activa
- Confirma que OLD se omite de la cadena tras limpiar la variable
Véase también
- [[feature—security—credential-key-rotation]]
- [[entity—core—config—credential-encryption-key]]
- [[entity—core—service—credential-manager]]
- [[concept—security—credential-encryption]]
- [[concept—security—key-rotation]]