8 min de lectura

Las pruebas de canales laterales temporales deben tratar el rechazo como un resultado

Las pruebas de canales laterales temporales ayudan a evitar que los agentes infieran el estado de la bóveda mediante éxitos, rechazos, credenciales inexistentes o credenciales no válidas.

Las pruebas de canales laterales temporales deben tratar el rechazo como un resultado

Un agente no necesita conocer un secreto para aprender algo peligroso. Si puede llamar repetidamente a una puerta de enlace de acciones y ordenar los resultados por duración, quizá descubra si la bóveda está bloqueada, si existe un nombre de credencial, si una solicitud pasó la autorización o si la puerta de enlace llegó a un servicio remoto.

Esa información basta para cambiar su comportamiento. Un agente de programación que descubre que existe una credencial puede seguir pidiendo acceso a ese servicio. Un agente comprometido puede usar el resultado para hacer reconocimiento. La fuga puede parecer inofensiva en una sola llamada. Se vuelve útil cuando quien llama controla las entradas, repite las solicitudes y puede medir el tiempo con precisión.

MITRE registra esta clase como CWE-208, Observable Timing Discrepancy. Su descripción es adecuadamente amplia: el estado interno relevante para la seguridad puede escapar cuando las operaciones tardan cantidades de tiempo observables diferentes. El ejemplo habitual es la comprobación de contraseñas. Una puerta de enlace para agentes tiene una versión menos conocida del mismo problema: quien llama ya está dentro del flujo de trabajo del desarrollador y puede realizar muchas llamadas estructuradas a herramientas sin cansarse.

La solución no consiste en hacer que cada acción tarde exactamente lo mismo. Esa promesa suele ser falsa, especialmente cuando una solicitud HTTP o una conexión SSH sale de la máquina. El trabajo es más concreto y práctico: identificar los estados que un agente no debería poder distinguir, hacer comparable su tratamiento local y mantener una suite de pruebas diferenciales que detecte nuevas rutas rápidas.

Trata el estado de la bóveda como información que el usuario no debe inferir

Una bóveda bloqueada, una credencial inexistente, una acción rechazada y una credencial remota incorrecta son condiciones operativas distintas. No son automáticamente datos diferentes que el agente necesite conocer.

Empieza por anotar qué puede saber cada usuario. Parece obvio, pero los equipos suelen saltarse este paso y dejan que el orden de implementación decida la política de divulgación. Una búsqueda temprana en la bóveda revela si existe una credencial. Una comprobación temprana de autorización revela si un proceso tiene una sesión aprobada. Un error local inmediato revela que la bóveda está bloqueada. Cada atajo puede ser razonable por separado. Juntos proporcionan al usuario una sonda del estado.

En una puerta de enlace de acciones, separa estas preguntas:

  • ¿Puede este proceso solicitar una acción?
  • ¿Está disponible la bóveda para ejecutarla?
  • ¿Existe una asignación de credencial para esta acción?
  • ¿El servicio remoto aceptó la credencial?
  • ¿Puede quien llama ver alguna de esas respuestas directamente o solo recibir el resultado de una acción?

La distinción importante es entre el estado de autorización y el estado de la credencial. La autorización responde si una ejecución concreta del agente puede invocar una acción. El estado de la credencial responde si la puerta de enlace tiene el material necesario para ejecutar esa acción. Si los mezclas internamente, un resultado temporal puede decirle por accidente al agente que existe una credencial simplemente porque la puerta de enlace la comprobó después de aprobar la solicitud.

El bloqueo de la bóveda de Sallyport es deliberadamente absoluto: mientras la bóveda está bloqueada, se rechaza toda acción. Es un límite de seguridad claro, pero aun así merece pruebas de tiempo, porque quien llama puede observar cómo se produce el rechazo. El objetivo no es fingir que una bóveda bloqueada puede completar una solicitud remota. Es asegurarse de que el tratamiento local del rechazo no cree una firma sencilla y repetible que revele más de lo necesario.

OWASP plantea lo mismo en su Authentication Cheat Sheet. Un texto de error genérico no elimina por sí solo una fuga de enumeración si una ruta de fallo realiza más trabajo que otra. La guía habla de autenticación, pero la lección de ingeniería se aplica aquí: un mensaje uniforme que envuelve rutas de ejecución diferentes sigue filtrando información mediante el tiempo transcurrido.

Cuatro resultados necesitan dos contratos temporales distintos

Intentar igualar todos los resultados es una recomendación popular porque resulta fácil de expresar. También es incorrecta cuando una puerta de enlace puede llamar a redes. Necesitas dos contratos temporales, no una duración universal imposible.

El primer contrato cubre los resultados locales. Son estados en los que la puerta de enlace debe rechazar la solicitud antes de enviar nada: la bóveda está bloqueada, falta la autorización de sesión o ha sido rechazada, una acción no tiene una credencial configurada o se ha rechazado una aprobación por llamada. Para los estados que deben revelar la misma cantidad de información al agente, usa una respuesta local común.

El segundo contrato cubre los resultados enviados. Tanto una credencial válida como una no válida pueden llegar al mismo servidor HTTP de prueba o al mismo host SSH de prueba. Sus tiempos totales incluyen el transporte, la reutilización de conexiones, el trabajo del servidor y la entrega de la respuesta. No puedes hacer que Internet tenga un tiempo constante. Sí puedes asegurarte de que la puerta de enlace inserte, envíe, registre y traduzca ambos resultados mediante rutas comparables, y después usar un servidor controlado para mantener estable la parte remota durante la prueba.

Esto produce una matriz útil:

Resultado¿Sale la solicitud de la puerta de enlace?¿Con qué debe compararlo la prueba de tiempo?
Bóveda bloqueadaNoOtros rechazos locales que no deban revelar más estado
Autorización rechazadaNoOtros rechazos locales, medidos antes de la interacción humana
Credencial inexistenteNoFallo local con la bóveda disponible, usando la misma envoltura de respuesta cuando la política de divulgación lo exija
Credencial no válidaCredencial válida contra el mismo servicio ascendente controlado
Credencial válidaCredencial no válida y variantes de error remoto

No compares directamente una credencial inexistente con una llamada exitosa a una API de terceros y declares que la prueba ha fallado porque una es más rápida. Esa prueba solo demuestra que una solicitud que nunca salió de la máquina es más rápida que una solicitud de Internet. Eso ya lo sabías.

Prueba los límites por separado. Un usuario local debería tener dificultades para separar los estados locales que quieres ocultar. Un usuario que envía solicitudes debería tener dificultades para distinguir una credencial de prueba buena de una mala basándose en el trabajo añadido por la puerta de enlace. El servidor de prueba puede devolver códigos de estado distintos deliberadamente después del mismo retraso, de modo que el resultado semántico siga siendo diferente y el experimento temporal continúe siendo útil.

Hay un límite claro: si quien llama recibe un error detallado que dice «credencial inexistente», ya no necesita usar el tiempo para saberlo. Las defensas temporales no pueden salvar una API que informa libremente del estado secreto. Decide primero qué semántica de errores está permitida.

Un fallo rápido se convierte en un oráculo cuando las llamadas pueden repetirse

Una fuga temporal rara vez aparece como una diferencia espectacular. Lo más habitual es que alguien añada un retorno anticipado razonable durante una refactorización.

Imagina una puerta de enlace con este orden de operaciones:

  1. Analizar la solicitud del agente.
  2. Buscar la credencial indicada en el índice de la bóveda.
  3. Comprobar si el proceso del agente tiene aprobación de sesión.
  4. Construir y enviar la solicitud.

Una credencial inexistente termina en el paso dos. Una credencial existente con un proceso no aprobado continúa hasta el paso tres. La respuesta externa podría ser idéntica en ambos casos: «acción no disponible». Sin embargo, la segunda ruta incluye un acierto en el índice de la bóveda, una búsqueda de autorización, la preparación de la auditoría y quizá la creación de una tarjeta de aprobación. Quien llama puede ejecutar cada entrada muchas veces y ordenar los resultados.

La fuga empeora cuando el agente puede elegir alias de credenciales. Puede probar una lista de nombres como staging, production, deploy o los nombres que haya encontrado en un repositorio. No necesita ejecutar una acción con éxito. Solo necesita separar un grupo rápido de uno lento.

El orden defensivo depende de tu política de divulgación, pero una estructura más segura sería:

  1. Validar la solicitud sin ramas que dependan de secretos.
  2. Aplicar el bloqueo absoluto de la bóveda.
  3. Aplicar la autorización del proceso o de la sesión.
  4. Resolver la acción y la credencial solo después de que el usuario haya superado los controles que deben preceder a ese conocimiento.
  5. Hacer que los fallos locales que deban permanecer indistinguibles pasen por el mismo trabajo de registro, preparación del error y finalización de la respuesta.

No interpretes esto como una instrucción para realizar trabajo secreto destinado a un proceso no autorizado. No debes descifrar una credencial ni construir un encabezado de autorización real solo para perder tiempo. El objetivo es evitar atajos dependientes del estado en el límite observable, no convertir los rechazos en una forma de acceder a secretos.

Un parche defectuoso habitual es sleep(100ms) antes de cada rechazo. Hace más bonito el gráfico de una demostración, pero crea tres problemas. La duración suele variar después por el ruido del planificador y el comportamiento de la caché. El retraso perjudica a los usuarios legítimos. Sobre todo, quien llama repetidamente puede eliminar mediante promedios el relleno aleatorio o fijo si las rutas subyacentes siguen siendo diferentes. Igualar el trabajo necesario es más fiable que añadir retrasos encima de un trabajo desigual.

Mide en el límite que realmente observa el agente

La instrumentación dentro de la puerta de enlace sirve para diagnosticar, pero no es la medición de seguridad principal. El agente observa el tiempo entre el envío de una llamada a una herramienta y la recepción de su resultado final. Ahí empieza y termina tu prueba diferencial de extremo a extremo.

Usa un controlador de pruebas dedicado que se comporte como un cliente de agente. Debe comenzar con una identidad de proceso conocida, enviar una solicitud, esperar una respuesta completa, registrar una duración monotónica y guardar la etiqueta del resultado fuera de la solicitud medida. No muestres etiquetas durante la ejecución. La salida de consola, los exportadores de trazas y los registros de depuración pueden distorsionar las rutas locales cortas y ocultar la regresión que buscas.

Un registro de muestra práctico necesita más de un número:

{
  "case": "vault_locked",
  "sequence": 184,
  "elapsed_us": 12746,
  "result_class": "local_denial",
  "connection_mode": "fresh",
  "run_id": "test-run-7"
}

Usa un reloj monotónico. Los relojes de pared saltan cuando se ejecuta la sincronización horaria y son instrumentos deficientes para comparar intervalos inferiores a un segundo. Registra microsegundos o nanosegundos si la plataforma los ofrece y muestra milisegundos cuando las personas lean los resultados. La precisión del archivo no implica exactitud de la medición, pero evita perder información antes del análisis.

Ejecuta una fase de calentamiento antes de recoger muestras. Las primeras llamadas pueden iniciar la aplicación, cargar código, inicializar un identificador de bóveda, crear un grupo de conexiones o llenar una caché. Esos efectos son reales desde el punto de vista operativo, pero a menudo eclipsan la diferencia estable que necesitas examinar. Prueba por separado el arranque en frío si los agentes pueden observarlo. No descartes en silencio el comportamiento incómodo de la primera llamada solo porque afee los gráficos.

Aleatoriza el orden de los casos. Si ejecutas 500 llamadas con la bóveda bloqueada y después 500 con credenciales inexistentes, el estado térmico, la recolección de basura, la actividad en segundo plano y la reutilización de conexiones se convierten en factores de confusión. Intercala los casos mediante una mezcla con semilla para que los fallos puedan reproducirse.

Alterna también conexiones nuevas y reutilizadas cuando el protocolo del cliente admita ambas. Una fuga que desaparece con una conexión caliente puede seguir importando si un agente crea clientes de corta duración. Una fuga que solo aparece con la reutilización puede revelar una caché indexada por la existencia de la credencial.

Construye un servicio ascendente controlado que separe la semántica del retraso

Evita otro motor de políticas
Sallyport usa una escalera fija de decisiones con tres controles, no un lenguaje de políticas ni un motor de reglas.

Las credenciales no válidas son el caso de prueba que más suelen hacer mal los equipos. Apuntan el sistema de pruebas a un servicio real, envían un token deliberadamente incorrecto y lo comparan con una llamada exitosa. Los límites de velocidad del proveedor, el enrutamiento regional, la reanudación de sesiones TLS y los controles contra abusos pasan a formar parte del resultado. Eso no es una prueba temporal de la puerta de enlace.

Construye un pequeño servidor de pruebas bajo tu control. Debe leer una credencial de prueba conocida con el mismo formato de encabezado que inserta la puerta de enlace, esperar una cantidad fija de trabajo y devolver un cuerpo y un estado distintos para las credenciales buenas y malas. No debe acortar la ruta de la credencial no válida.

Por ejemplo, este contrato del servidor de prueba es suficiente:

Request header: Authorization: Bearer test-good
Response: 200 {"fixture":"accepted"}

Request header: Authorization: Bearer test-bad
Response: 401 {"fixture":"rejected"}

Both requests: wait until the same server-side target duration has elapsed

La duración objetivo debe ser mayor que el ruido habitual del planificador local, pero lo bastante corta para que la suite siga siendo rápida. Elígela a partir de mediciones realizadas en tu propia máquina de pruebas, en lugar de copiar un número de una publicación. Lo importante es que ambas ramas del servidor de prueba ejecuten la misma ruta de análisis, reloj, espera y respuesta antes de diferenciarse semánticamente.

En HTTP, ejecuta el servidor de prueba en loopback cuando quieras aislar la puerta de enlace y el cliente. Ejecútalo en un host remoto controlado en una segunda tarea cuando quieras observar cómo afecta el ruido normal de la red a la detección. Mantén esos informes separados. Un resultado de loopback indica si cambió la implementación local. Un resultado remoto indica si la prueba sigue siendo sensible bajo variaciones de transporte realistas.

Para SSH, usa una cuenta de prueba y un comando que termine de una forma conocida después de la autenticación. No hagas pruebas fallando repetidamente contra un bastión de producción. Los servidores SSH pueden ralentizar deliberadamente los fallos, bloquear cuentas o añadir trabajo de registro. Son defensas razonables, pero hacen que la medición hable del servidor y no de la puerta de enlace.

Sallyport envía solicitudes HTTP con inserción de credenciales bearer, básicas o de encabezado personalizado, y usa su asistente sin estado sp-ssh incluido para SSH. Son canales separados y necesitan servidores de prueba separados. Un resultado uniforme para una ruta de encabezado HTTP no dice nada sobre una ruta SSH que resuelve claves, inicia un asistente y negocia una conexión.

Compara distribuciones y después intenta clasificar el estado

Las medias ocultan las fugas temporales. Si el 90 % de las llamadas tarda 12 milisegundos y el 10 % tarda 80 porque una caché solo falla para una credencial existente, la media puede parecer suficientemente cercana a la de otro caso, aunque un agente pueda aprovechar el grupo rápido.

Para cada caso, conserva el conjunto completo de muestras. Informa al menos de la mediana, los percentiles inferior y superior, el mínimo, el máximo y el número de muestras. Un histograma suele revelar más que una tabla porque muestra inmediatamente dos grupos.

Después haz que la prueba sea adversarial. Entrega a un clasificador deliberadamente sencillo solo la duración transcurrida y pídele que adivine la etiqueta oculta. Empieza con un clasificador por umbral. Elige un único límite, por ejemplo «menos de X microsegundos significa que falta la credencial», e informa de la precisión con datos que no se hayan usado para elegir ese límite. Si un clasificador de un solo umbral supera repetidamente la línea base por un margen amplio, existe una señal observable que merece investigación.

Un pequeño script de análisis en Python puede hacer visible esta regresión sin fingir que demuestra un tiempo criptográfico constante:

from statistics import median

samples = {
    "vault_locked": [...],
    "credential_missing": [...],
}

for name, values in samples.items():
    ordered = sorted(values)
    p10 = ordered[int(len(ordered) * 0.10)]
    p90 = ordered[int(len(ordered) * 0.90)]
    print(name, {"n": len(values), "p10": p10,
                 "median": median(values), "p90": p90})

best = None
all_values = sorted(set(samples["vault_locked"] + samples["credential_missing"]))
for cutoff in all_values:
    correct = 0
    total = 0
    for label, values in samples.items():
        for value in values:
            guess = "vault_locked" if value <= cutoff else "credential_missing"
            correct += (guess == label)
            total += 1
    score = correct / total
    if best is None or score > best[0]:
        best = (score, cutoff)

print({"best_training_accuracy": best[0], "cutoff_us": best[1]})

Separa las muestras en grupos de entrenamiento y de validación antes de seleccionar el límite. De lo contrario, el script se ajustará demasiado al ruido y se felicitará a sí mismo. Si añades un clasificador más complejo, úsalo como diagnóstico secundario. Un modelo complicado puede encontrar patrones diminutos que ningún agente práctico pueda aprovechar, mientras que un umbral sencillo revela las fugas embarazosas que los ingenieros introducen de verdad.

No establezcas una condición universal como «todas las medianas deben estar a menos de cinco milisegundos». Ese umbral no significa lo mismo en máquinas y configuraciones diferentes. Usa una línea base registrada en tu entorno controlado, comprueba si las distribuciones se superponen como esperas y haz fallar la prueba cuando un cambio cree una separación estable entre estados que querías ocultar.

La comparación de tiempo constante resuelve un problema más pequeño

Revoca una ejecución sospechosa del agente
El registro Sessions sigue las ejecuciones de los agentes y permite revocar una sesión activa al instante.

Cuando oyen «ataque temporal», los desarrolladores suelen recurrir a una función de igualdad en tiempo constante. Esa función importa al comparar secretos, firmas, MAC y tokens de la misma longitud. No hace que toda la ruta de una solicitud de la puerta de enlace tenga un tiempo constante.

El paquete crypto/subtle de Go proporciona ConstantTimeCompare para segmentos de bytes con contenido de igual longitud. Es el tipo de primitiva adecuado cuando la propia comparación secreta necesita un comportamiento independiente de los datos. Pero no puede igualar una rama que retorna antes de abrir la bóveda, una rama que muestra una tarjeta de aprobación o una rama que abre una conexión de red.

Usa comparaciones de tiempo constante cuando compares valores sensibles y de formato fijo. Después revisa el flujo de control que las rodea. Una comparación limpia dentro de una ruta que retorna inmediatamente si falta una credencial sigue dejando un oráculo sobre la presencia de esa credencial.

Por eso también debes evitar llamar a todo el problema «tiempo constante». Para una puerta de enlace de escritorio que puede realizar llamadas HTTP y SSH, el tiempo constante de extremo a extremo no es alcanzable ni necesario. El requisito es más concreto: los estados locales sensibles no deben crear una señal temporal que el usuario pueda clasificar fácilmente.

Los ejemplos de CWE-208 de MITRE incluyen salidas anticipadas durante las comprobaciones de contraseñas y trabajos diferentes para cuentas existentes e inexistentes. El patrón es el mismo aunque no haya ninguna comparación de contraseñas. La diferencia observable proviene de la ruta de decisión, no de un único operador de igualdad inseguro.

Los flujos de aprobación necesitan un límite de medición explícito

La aprobación por sesión y por llamada introduce a una persona en la línea temporal. La duración de la llamada completa incluye el tiempo que alguien tarda en ver una tarjeta, leer la identidad del proceso, decidir, autenticarse con Touch ID y hacer clic. Esa duración varía por razones ajenas al estado de la bóveda.

No intentes ocultarlo con relleno. Empeorarás la interacción y aun así no conseguirás que las personas actúen siguiendo un reloj.

En su lugar, divide el flujo en partes automáticas y controladas por una persona. La parte automática empieza cuando el agente envía la llamada y termina cuando la puerta de enlace produce un rechazo sin mostrar un aviso o presenta una solicitud de aprobación. Mide esa parte entre los distintos estados. La parte humana comienza cuando se muestra la solicitud y termina con la aprobación, el rechazo, el tiempo agotado o la salida del proceso. Regístrala para operaciones, pero no la uses como objetivo de equivalencia temporal de un canal lateral.

También necesitas un modo de prueba que establezca un estado de aprobación estable antes de tomar muestras de las llamadas enviadas. De lo contrario, la distribución de tu «credencial válida» incluirá una tarjeta de aprobación una vez y la omitirá durante el resto de la sesión. Esto produce un valor atípico enorme en la primera muestra y oculta diferencias más sutiles.

Una buena suite debe tener casos distintos para estas preguntas:

  • ¿Una bóveda bloqueada rechaza la solicitud antes de cualquier búsqueda de credenciales que dependa de la aprobación?
  • ¿Un proceso no aprobado recibe el mismo tratamiento previo al aviso independientemente de que una acción tenga una credencial configurada?
  • Después de aprobar una sesión, ¿las credenciales de prueba válidas y no válidas siguen rutas comparables hasta el servidor ascendente controlado?
  • ¿El rechazo de una aprobación por llamada expone trabajo adicional dependiente de la credencial antes de mostrar la solicitud?

Sallyport identifica un proceso de agente nuevo mediante su autoridad de firma de código en la tarjeta de aprobación, y su autorización por sesión dura solo mientras se ejecuta ese proceso. La suite temporal debe crear procesos de agente nuevos deliberadamente al probar el comportamiento de la primera llamada y mantener vivo un proceso conocido al probar una sesión aprobada. Mezclar esos modos hace imposible interpretar el resultado.

El trabajo de auditoría no debe crear una ruta rápida dependiente del secreto

Verifica el registro sin conexión
Verifica sin conexión la cadena de auditoría cifrada de Sallyport con sp audit verify, sin una clave de bóveda.

Los registros de auditoría suelen causar la última fuga temporal porque se consideran tareas administrativas y no parte del límite de seguridad. Una solicitud rechazada puede registrar solo un evento breve. Una solicitud exitosa puede reservar un registro detallado, calcular su hash para una cadena y escribirlo en almacenamiento cifrado. Esa diferencia puede ser legítima si el éxito ya es observable. Es peligrosa cuando dos rechazos locales revelan cantidades diferentes de un estado oculto.

Decide qué campos puede registrar cada resultado de forma segura y haz que los fallos locales equivalentes realicen un trabajo de auditoría equivalente. No necesitas escribir credenciales ficticias ni enviar solicitudes de prueba. Sí debes evitar una rama en la que «credencial inexistente» omita el diario mientras «bóveda bloqueada» realiza una búsqueda y escribe un registro más pesado, si el agente no debe distinguirlas.

Mantén la verificación de auditoría fuera de la ruta de solicitudes. La verificación es una acción del operador con otro propósito y otro perfil temporal. La cadena de auditoría de Sallyport puede verificarse sin conexión sobre el texto cifrado con sp audit verify, sin una clave de bóveda. Ese diseño evita que la verificación necesite leer un secreto, pero no elimina la necesidad de probar el comportamiento de las solicitudes alrededor del registro.

Añade intervalos internos alrededor del análisis de solicitudes, la autorización, el bloqueo de la bóveda, la resolución de credenciales, la adición de auditoría, el envío y el mapeo de respuestas. No expongas esos intervalos al agente. Cuando la prueba de extremo a extremo encuentre una separación, compara las duraciones agregadas de los intervalos entre casos para localizar la etapa que acaba de divergir.

El error es añadir trazas detalladas solo después de que aparezca una regresión temporal. Añade la instrumentación pronto, protégela mediante una opción de pruebas o diagnósticos locales y asegúrate de que la ruta normal no emita registros síncronos cuyo coste dependa de una credencial o de un resultado.

Coloca las pruebas diferenciales junto al código que añade ramas

Una suite temporal debe revisarse junto con las pruebas de autorización. Las ramas con más probabilidades de retroceder suelen formar parte de cambios de mantenimiento corrientes: un atajo para una configuración ausente, una caché de alias de credenciales, un campo nuevo de auditoría, un mensaje de error mejor o una refactorización que mueve la búsqueda en la bóveda antes de la aprobación del proceso.

Ejecuta una suite local compacta en cada cambio que afecte al acceso a la bóveda, la autorización, la resolución de acciones, el mapeo de errores, la configuración del transporte o las escrituras de auditoría. Puede usar servidores de loopback y un número moderado de muestras. Ejecuta una suite aleatoria más larga en un entorno controlado y tranquilo antes de los lanzamientos, registrando por separado los modos en frío y caliente.

Haz que la prueba produzca algo que un revisor pueda utilizar. Esto es mejor que un indicador verde con una puntuación agregada inexplicable:

case pair: vault_locked vs credential_missing
samples: 400 per case, randomized order
median: 12.7 ms vs 13.1 ms
p10-p90: 11.8-14.0 ms vs 11.9-14.3 ms
holdout threshold accuracy: 51.4%
result: within baseline

Y esto es mejor que ocultar el problema bajo un fallo de rendimiento genérico:

case pair: vault_locked vs credential_missing
samples: 400 per case, randomized order
median: 4.2 ms vs 19.6 ms
p10-p90: 3.9-4.7 ms vs 18.2-22.1 ms
holdout threshold accuracy: 99.1%
result: investigate credential lookup before authorization

El segundo informe no afirma que un atacante siempre vaya a obtener una precisión del 99,1 % en una estación de trabajo ocupada. Indica al ingeniero que el código local ha creado una separación clara y repetible. Basta para bloquear el cambio hasta corregir el orden de las ramas o la envoltura de respuesta.

No ocultes el resultado con un retraso arbitrario. Mueve el trabajo dependiente de secretos detrás del control correcto, elimina el trabajo innecesario específico de cada estado y vuelve a probar desde el límite del agente. El resultado útil no es un gráfico perfectamente plano. Es un agente que no puede convertir un cronómetro en un inventario de lo que hay detrás de la bóveda.

FAQ

¿Una bóveda bloqueada y una credencial inexistente deben devolver el mismo error?

Pruébalos como estados separados, aunque la respuesta visible para el usuario sea deliberadamente parecida. Una bóveda bloqueada indica que la puerta de enlace no puede ejecutar ninguna acción; una credencial inexistente indica que la acción seleccionada no está configurada; una credencial no válida indica que la solicitud llegó al servicio remoto y falló allí. Si esas rutas tienen tiempos locales muy distintos, el agente aún puede clasificarlas.

¿Cómo pruebo el tiempo cuando una solicitud de aprobación requiere que una persona haga clic?

El retraso de una aprobación humana no es un objetivo de medición útil porque depende de una persona. Mide la parte automática antes de que aparezca la tarjeta de aprobación y prueba después la ruta aprobada con una autorización de prueba estable. No trates el tiempo de reacción del usuario como una medida de seguridad.

¿Basta con comparar el tiempo medio de respuesta en las pruebas de tiempo?

No. Una prueba que solo compara la duración media puede pasar por alto comportamientos multimodales, efectos de caché y una ruta rápida de fallo escondida dentro de una media ruidosa. Registra cada muestra, compara percentiles y prueba un clasificador sencillo que intente adivinar el estado a partir del tiempo transcurrido.

¿Cómo puedo probar credenciales no válidas sin llamar a una API real?

Usa un servidor de prueba controlado que reconozca una credencial de prueba válida y otra no válida, espere el mismo intervalo fijo para ambas y después devuelva códigos de estado diferentes. Así puedes medir el comportamiento de la puerta de enlace sin confundirlo con el comportamiento impredecible de una API de terceros. Nunca ejecutes pruebas de tiempo de gran volumen contra un proveedor en producción.

¿Añadir un retraso aleatorio corrige un canal lateral temporal?

No. El ruido aleatorio hace que una señal clara sea más difícil de detectar con pocas muestras, pero las mediciones repetidas pueden promediarlo. Además, ralentiza el uso normal y convierte el comportamiento temporal en un problema probabilístico. En su lugar, coloca el mismo trabajo necesario en rutas comparables.

¿Qué diferencia de tiempo es segura entre los resultados de autorización?

El objetivo útil es que un clasificador no pueda separar de forma fiable los estados que deben permanecer privados en el punto donde los mides. No existe un presupuesto universal en milisegundos, porque un proceso local, un servidor de loopback y una API de Internet tienen niveles de ruido diferentes. Conserva una línea base y haz fallar la prueba cuando un cambio de código cree una separación estable que antes no existía.

¿Los errores de red deben agruparse con las credenciales inexistentes?

Mantén los fallos de transporte en su propia categoría. Los problemas de DNS, una conexión rechazada y un tiempo de espera remoto pueden revelar condiciones de red, pero no necesariamente indican si existe una entrada en la bóveda. No agrupes fallos distintos de forma tan agresiva que los operadores pierdan la capacidad de diagnosticar problemas de conectividad.

¿Desde dónde debo medir el tiempo en una puerta de enlace para agentes?

Prueba desde el límite observable por el agente: desde que escribe la solicitud MCP hasta que recibe el resultado o error final. Añade también pruebas más específicas alrededor de la búsqueda en la bóveda, la autorización y el envío, para que una prueba diferencial fallida indique qué etapa retrocedió. Un cronómetro de extremo a extremo encuentra las fugas; los intervalos internos ayudan a explicarlas.

¿Las pruebas de tiempo pueden proteger secretos si el agente tiene acceso amplio?

Las pruebas pueden reducir la divulgación accidental, pero no pueden ocultar un hecho que el agente tiene autorización explícita para conocer. Si un agente puede enumerar nombres de credenciales, consultar pantallas de estado o recibir errores detallados diferentes, el tiempo ya no es el problema principal. Elimina primero la divulgación innecesaria del estado y después dificulta que las rutas restantes se clasifiquen por duración.

¿Con qué frecuencia debo ejecutar pruebas de canales laterales temporales?

Trata la suite de tiempo como una prueba de regresión, no como una auditoría única. Ejecuta una versión corta en cada cambio que afecte a la autorización, la búsqueda en la bóveda, el mapeo de errores o el envío de solicitudes, y ejecuta una muestra aleatoria más grande en un entorno controlado antes de cada lanzamiento. Las fugas temporales suelen volver cuando alguien añade un retorno anticipado que parece inofensivo.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov