Volver a la wiki

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

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

  1. Antes de rotación: Vacía ("")
  2. Inicia rotación: Se establece en Dokploy/orquestador a la clave antigua
  3. Se ejecuta reencrypt_credentials: Migra todo ciphertext a la nueva clave
  4. Se limpia: Se borra de entorno; la app no la lee más
  5. 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

Test

Validado en tests/test_credential_key_rotation.py::test_rotation_via_old_key:

Véase también

Subir