Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Puedes recuperar varios secretos de forma concurrente con asyncio y mantener libre el bucle de eventos mientras esperas la respuesta del gestor, pero solo si el cliente que usas ofrece una operación realmente asíncrona. Eso es una ventaja de concurrencia, no de seguridad. La confidencialidad de una credencial depende del gestor, de la identidad con la que te autenticas, de los permisos concedidos, del transporte, de lo que registras y del tiempo que el valor permanece en texto claro dentro de tu proceso.

Qué aporta asyncio y qué no

Una corutina que hace await sobre una operación de red cede el control al bucle de eventos, que puede avanzar otras tareas hasta que llegue la respuesta. La documentación oficial de Python describe asyncio como una biblioteca para escribir código concurrente con la sintaxis async/await, orientada a operaciones de red y de entrada/salida. La palabra clave es «realmente»: la cesión del control solo ocurre si la llamada subyacente es asíncrona.

Por eso una función declarada con async def no es no bloqueante por el hecho de serlo. Si dentro de ella invocas un cliente síncrono, el bucle queda detenido durante toda la llamada.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Situación Qué ocurre en el bucle de eventos Condiciones y riesgos
Cliente con operación asíncrona real, invocada con await Otras corutinas avanzan mientras esperas la red La mejora debe medirse en tu sistema; ninguna cifra general es aplicable
Cliente síncrono dentro de async def El bucle se bloquea durante toda la llamada Envolver la llamada en una función asíncrona no cambia este comportamiento
Cliente síncrono delegado a un hilo con asyncio.to_thread o a un executor El bucle queda libre; la llamada ocupa un hilo del pool El número de hilos es limitado; si la tarea se cancela, la llamada en curso en el hilo no se interrumpe; las exigencias de seguridad no cambian

Lo que asyncio no toca es quién puede leer el secreto, cómo viaja, dónde permanece en memoria y qué termina en los registros. Esos puntos son los que determinan la seguridad, y se tratan en las secciones siguientes.

Recuperar varios secretos sin bloquear el bucle

La concurrencia tiene sentido cuando los secretos que necesitas son independientes entre sí. El patrón siguiente no depende de un SDK concreto: get_value es la corrutina de lectura de tu cliente asíncrono. Verifica su nombre y su firma en la versión que instalas antes de usarlo.

import asyncio

async def recuperar(get_value, nombre: str, plazo: float = 5.0) -> str:
    return await asyncio.wait_for(get_value(nombre), timeout=plazo)

async def cargar_secretos(get_value) -> dict[str, str]:
    nombres = ["db/password", "payments/api-token", "tls/key-passphrase"]
    resultados = await asyncio.gather(
        *(recuperar(get_value, nombre) for nombre in nombres),
        return_exceptions=True,
    )
    secretos = {}
    for nombre, resultado in zip(nombres, resultados):
        if isinstance(resultado, BaseException):
            # Solo el nombre y el tipo de error; nunca el valor
            raise RuntimeError(
                f"No se pudo recuperar '{nombre}' ({type(resultado).__name__})"
            ) from None
        secretos[nombre] = resultado
    return secretos

Hay tres decisiones en ese código que conviene entender:

  • asyncio.wait_for cancela la corrutina cuando vence el plazo. Comprueba que tu cliente libera sus conexiones y no deja operaciones a medias al recibir la cancelación.
  • Sin return_exceptions=True, gather propaga el primer error, pero las demás corutinas no se cancelan automáticamente y siguen ejecutándose. Con el argumento activado, gather espera a que todas terminen antes de que tu código decida qué hacer.
  • Si varios consumidores comparten una misma llamada remota, decide antes quién cancela, cómo se reintenta y cuándo se descarta un valor almacenado tras una rotación. Esas políticas dependen del servicio y del framework que uses.

Controles del ciclo de vida del secreto

La guía de gestión de secretos de OWASP incluye como ejemplos de secretos las claves de API, las credenciales de base de datos, los permisos IAM, las claves SSH y los certificados. Recomienda almacenamiento centralizado o estandarizado cuando corresponde, controles de acceso granulares, automatización de la gestión y rotación, y un ciclo de vida que cubra creación, rotación, revocación y expiración. Estos controles son independientes de si el cliente es síncrono o asíncrono.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Identidad y mínimo privilegio

  • Autentica la aplicación con la identidad que ofrece tu entorno, por ejemplo un rol asociado a la carga de trabajo, en lugar de una clave estática copiada en el código.
  • Concede solo las operaciones necesarias sobre los secretos que ese proceso utiliza. Una aplicación que lee no debería poder crear ni borrar.
  • Separa las identidades por servicio para que la auditoría atribuya cada acceso a un componente concreto.

Rotación, revocación y expiración

La frecuencia de rotación depende del propósito y del riesgo de cada secreto. No existe un intervalo universal que puedas copiar. Antes de rotar, decide qué hace la aplicación con el valor nuevo: si lo lee al arrancar, necesitará reinicio; si lo relee bajo demanda, puede adoptarlo sin interrupción. Un valor revocado que siga en uso provoca fallos que parecen aleatorios, así que la secuencia de cambio debe estar escrita.

Auditoría y supervisión

  • Registra quién accede a cada secreto y configura alertas para accesos que no siguen el patrón habitual.
  • Usa TLS en todo el transporte entre la aplicación y el gestor, tal como recomienda OWASP.

Respaldo y recuperación

  • Prueba la restauración de las copias de secretos. Un respaldo que nunca se ha restaurado no garantiza recuperación.
  • Define un procedimiento de emergencia: quién puede revocar un secreto comprometido y cómo se rota sin detener el servicio.

Exposición en memoria y caché

En Python las cadenas son inmutables, por lo que no puedes borrar de forma fiable su contenido de memoria. El control práctico es reducir el tiempo y el número de lugares donde el valor existe.

  • Recupera el secreto cuando vas a usarlo, no al importar el módulo ni al definir una constante global.
  • Mantén el valor en una variable local de la función que lo necesita y deja de referenciarlo cuanto antes.
  • No lo guardes en cachés sin expiración. Una caché es un nuevo lugar donde el secreto permanece.
  • Evita copias innecesarias, como serializarlo a JSON para un log o incrustarlo en una URL.

Una corutina suspendida conserva sus variables locales. Si el secreto está en una de ellas, sigue en memoria mientras la tarea espera la red, y un proceso de larga duración puede mantenerlo durante horas. Guardar un secreto en memoria mientras se usa no es inseguro por sí mismo; lo que determina el riesgo es cuánto dura, quién más puede leer el proceso y cuántas copias existen.

Registros, errores y línea de comandos

  • No pases secretos como argumentos de línea de comandos: aparecen en los listados de procesos y pueden quedar en el historial de la shell.
  • No incluyas el valor en mensajes de excepción, en trazas ni en el repr de objetos. Si defines una clase que contiene un secreto, sobrescribe __repr__ para ocultarlo.
  • Configura el logger para registrar el nombre del secreto y el tipo de error, nunca su contenido.
  • Los SDK pueden registrar parámetros de la solicitud. AWS indica que no se incluyan datos sensibles en parámetros de solicitud, salvo en los campos designados para el valor secreto, porque otros parámetros pueden registrarse. Revisa la configuración de logs de tu SDK o de tu capa HTTP antes de activar la depuración.

Generar valores aleatorios con secrets

Para tokens, contraseñas temporales o claves de sesión, usa el módulo secrets. La documentación de Python lo describe así: «The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.» La misma documentación indica que debe preferirse a random, que está pensado para modelado y simulación y no para seguridad. La documentación de seguridad de Python repite esa recomendación.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import secrets

token = secrets.token_urlsafe(32)  # 32 bytes = 256 bits, codificados en Base64 URL-safe

La página del módulo contiene una indicación histórica: «As of 2015», se consideraban suficientes 32 bytes (256 bits) para el uso típico previsto. Es una referencia de contexto, no una recomendación vigente, y la propia documentación advierte que el valor predeterminado puede cambiar en cualquier momento. Elige el tamaño según tu caso y la guía que aplique en tu organización.

secrets genera valores; no los almacena. Escribe el valor en el gestor en cuanto lo creas y no lo imprimas en la consola.

Contenedores y CI/CD

Contenedores

OWASP describe dos modalidades: recuperar el secreto desde el gestor en memoria al arrancar, o usar un sidecar de vida corta que lo obtiene y lo entrega localmente. Ninguna es universalmente mejor; la elección depende de tu orquestador y de quién controla la identidad del sidecar.

  • Con recuperación al arrancar, el valor no queda en la imagen ni en la definición del despliegue, pero una rotación exige relectura o reinicio, como vimos antes.
  • Con un sidecar, define qué identidad tiene y cómo se limita su acceso frente al resto de contenedores del mismo grupo.
  • Evita variables de entorno definidas en los manifiestos, archivos de configuración con credenciales y secretos incorporados en la imagen. OWASP advierte sobre la exposición por estas vías.
  • Si el orquestador ofrece su propio almacén de secretos, evalúa sus controles de acceso y su cifrado antes de tratarlo como equivalente al gestor dedicado.

CI/CD

  • El job que necesita la credencial debe recuperarla en el momento de uso, en lugar de copiarla a variables globales del pipeline.
  • Usa identidades de servicio limitadas por pipeline o por entorno, de modo que cada acción quede atribuida.
  • No concedas a la herramienta de pipeline acceso amplio a todo el material secreto. OWASP recomienda evitarlo.

Ejemplo con AWS Secrets Manager y sus límites

Para lectores que ya usan AWS, la referencia del SDK de AWS para Python describe un cliente llamado AsyncSecretsManagerClient y una operación create_secret asíncrona. Esa referencia describe además el valor del secreto como almacenado cifrado. Estos datos prueban que el SDK documentado ofrece esa interfaz; no prueban que todos los SDK de nube sean asíncronos, ni que cada llamada asociada tenga el mismo tratamiento de cifrado.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Confirma en la versión exacta del SDK instalada que el cliente asíncrono existe y que la operación que vas a usar es awaitable.
  2. Asigna la identidad mediante el mecanismo de tu entorno, por ejemplo un rol de IAM vinculado a la carga de trabajo, con permisos sobre los secretos concretos que necesita.
  3. Pasa el valor únicamente en el campo designado para el secreto. No lo incluyas en nombres, descripciones ni etiquetas.
  4. Revisa qué parámetros de la llamada se registran en tu entorno. No des por hecho que todo lo que envías recibe el mismo cifrado que el valor.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Criterios para evaluar un gestor o un SDK

La guía de OWASP trata estos ejes como parte de la selección y operación de un gestor de secretos, pero no compara proveedores entre sí. Usa la lista como base de tu propia comparación:

  • Soporte asíncrono real en el SDK y la versión que usas.
  • Identidad de carga de trabajo y granularidad de permisos por secreto y por operación.
  • Rotación, revocación, credenciales dinámicas y expiración.
  • Auditoría y alertas sobre accesos.
  • Cifrado en almacenamiento y en transporte, y control sobre las claves.
  • Disponibilidad, límites de servicio, recuperación y operación de emergencia.
  • Integración con despliegue, contenedores y CI/CD.

Solución de problemas

Otras tareas se detienen mientras se recupera un secreto

Causa probable: una llamada síncrona dentro de una corutina. Cómo confirmarlo: ejecuta la aplicación con el modo debug de asyncio, con PYTHONASYNCIODEBUG=1 python app.py o con asyncio.run(main(), debug=True). En ese modo, asyncio registra los callbacks que superan el umbral slow_callback_duration, cuyo valor por defecto es 0,1 segundos. El modo debug añade sobrecarga, así que úsalo en pruebas. Recuperación: sustituye la llamada por la versión asíncrona verificada del cliente o delégala a un hilo con límites explícitos.

Un secreto aparece en un registro

Causas habituales: un log del SDK que incluye parámetros de la solicitud, una traza con el valor en un mensaje de excepción o un f-string que lo interpola. Recuperación: considera comprometido el valor y rótalo de inmediato. Después elimina o restringe los registros afectados según tu política de retención, corrige el punto de origen y añade una comprobación que impida repetirlo.

Algunas recuperaciones fallan y otras no

Causa probable: un error parcial en gather. Cómo confirmarlo: revisa el mapeo entre nombres y resultados del ejemplo de este artículo. Recuperación: reintenta solo los secretos fallidos, con un número máximo de intentos y espera creciente entre ellos, y no conserves los valores parciales en disco.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

La aplicación sigue usando el valor anterior tras una rotación

Causa probable: el valor se guardó en memoria al arrancar y nunca se relee. Recuperación: reinicia el proceso o implementa la relectura según el diseño elegido en la sección de rotación. Revoca el valor anterior solo después de confirmar que ningún consumidor lo usa.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.