7 min de lectura

La rotación de certificados TLS exige doble prueba

La rotación de certificados TLS acaba cuando la emisión coincide con una observación nueva y validada de cada endpoint activo.

La rotación de certificados TLS exige doble prueba

Una autoridad certificadora puede emitir exactamente el certificado solicitado por un agente de IA mientras el servicio sigue presentando el anterior. He visto tareas de rotación celebrar un PEM descargado, un secreto actualizado o un comando de recarga en verde, para descubrir en el peor momento que un listener nunca cambió. La emisión y el despliegue correctos son afirmaciones distintas, por lo que necesitan pruebas distintas.

Una rotación fiable registra qué emitió la CA, despliega ese mismo artefacto y abre una conexión TLS nueva para observar qué reciben los clientes. La comparación final debe usar una identidad estable del certificado, el hostname previsto y la ruta de red real. Si el agente no puede aportar ambos lados de la comparación, el cambio sigue en curso.

El cierre necesita un contrato de pruebas explícito

Una rotación solo termina cuando el registro del certificado emitido coincide con las observaciones de todos los endpoints incluidos en el despliegue. Escribe esa regla antes de dar credenciales o comandos a un agente. De lo contrario, optimizará para lo que su herramienta llame éxito, aunque solo sea una escritura de archivo y no un cambio visible para el cliente.

El registro de emisión debe incluir el identificador del pedido o solicitud, los nombres DNS pedidos, el número de serie, la huella SHA-256, el periodo de validez, el emisor y un resumen de la clave pública. También debe indicar dónde se guardaron la cadena completa y la clave privada sin copiar la clave al registro. La huella identifica el certificado hoja completo; el resumen de la clave pública permite saber si una reemisión conservó o cambió la clave.

El registro de despliegue responde otras preguntas: qué destino recibió el artefacto, qué configuración lo referencia, qué proceso aceptó una recarga y cuándo ocurrió. Una respuesta correcta de la API del plano de control pertenece aquí, pero no prueba el servicio. Solo demuestra que un intento de transición llegó al sistema de despliegue.

El registro de observación nace de una conexión nueva posterior al despliegue. Necesita el hostname solicitado, la dirección resuelta o forzada, el puerto, el número de serie y la huella observados, el resultado de validación, la hora y la ubicación del verificador. La ubicación importa porque una sonda interna, una externa y otra tras un proxy corporativo pueden llegar a terminaciones distintas.

Mantén mecánica la condición de cierre:

complete = issuance.valid
        && deployment.accepted
        && every(expected_endpoint,
                 observation.chain_valid
                 && observation.name_valid
                 && observation.leaf_fingerprint == issuance.leaf_fingerprint)

Así queda visible un estado incómodo: el certificado existe y se aceptó el despliegue, pero la huella servida aún difiere. Llámalo deployed_unverified, no complete. Los estados precisos impiden que un panel o el resumen del agente fusione dos afirmaciones.

La emisión ACME no demuestra el despliegue

ACME demuestra que una CA aceptó un pedido y emitió un certificado tras completar la autorización requerida, pero el protocolo no demuestra que tu aplicación lo sirva. RFC 8555 describe cuatro pasos principales: enviar el pedido, probar el control de los identificadores, finalizarlo con una solicitud de firma y esperar la emisión para descargar el certificado. El límite acaba en la descarga.

Ese límite se pierde de vista porque muchos clientes ACME ejecutan un hook de despliegue tras renovar. El hook queda fuera de la transacción con la CA. Puede fallar por una ruta cambiada, un contenedor con el secreto anterior, una recarga al proceso equivocado, una API remota que acepta una actualización asíncrona o un nodo inaccesible. El pedido sigue siendo válido en todos esos casos.

Registra el objeto final del pedido ACME o la respuesta equivalente de la CA. En ACME, status: valid y una URL de certificado poblada prueban la emisión. Captura los identificadores y la huella de la hoja devuelta tras analizar el certificado. No uses la mera existencia de un archivo nuevo como identidad del artefacto; los temporales, enlaces simbólicos y nombres reutilizados son pruebas pobres.

Certificate Transparency tampoco cierra el circuito. Una entrada puede mostrar que se emitió un certificado público para un nombre. No dice si el balanceador, ingress, servidor web o CDN ya lo presenta. CT aporta una prueba independiente de emisión, no vigila despliegues.

La diferencia cambia el tratamiento de errores. Un fallo de emisión significa que el agente nunca obtuvo la credencial prevista. Un fallo de despliegue significa que obtuvo una credencial sensible que quizá ya está almacenada, pero no se sirve. Este caso suele exigir limpieza, reintento o rollback y merece otra alerta.

Valida el artefacto antes del listener

Antes del despliegue, confirma que el certificado hoja contiene los nombres pedidos, la validez y el emisor previstos, y una clave pública que coincide con la privada. Esta barrera detecta bundles mal formados y archivos equivocados sin tocar producción. No sustituye la sonda activa.

RFC 9525 precisa la regla de identidad: los clientes construyen identificadores de referencia aceptables de forma independiente y los comparan con los del certificado. En servicios DNS normales, los nombres relevantes viven en subjectAltName. El RFC rechaza recurrir a un Common Name con aspecto de dominio. Un agente que solo compruebe subject=CN=... puede aprobar algo que los clientes modernos deben rechazar.

Inspecciona el artefacto hoja con campos de salida reales:

openssl x509 -in leaf.pem -noout \
  -serial -fingerprint -sha256 -dates -issuer -subject \
  -ext subjectAltName

La salida suele tener esta forma:

serial=03A17C...
sha256 Fingerprint=6B:19:8A:...
notBefore=Jul 24 08:15:00 2026 GMT
notAfter=Oct 22 08:14:59 2026 GMT
issuer=C=US, O=Example CA, CN=Example Issuing CA
subject=CN=api.example.net
X509v3 Subject Alternative Name:
    DNS:api.example.net, DNS:www.example.net

Usa openssl x509 -checkhost api.example.net -noout como barrera automática si tu versión lo admite. OpenSSL documenta -checkhost para comprobar la correspondencia con un host. Interpreta el código de salida, no un texto descriptivo que puede cambiar entre versiones.

Compara claves públicas sin exponer material privado. Estos comandos calculan el hash de la clave pública codificada en DER en ambos lados; dos líneas iguales muestran que certificado y clave forman pareja:

openssl x509 -in leaf.pem -pubkey -noout \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256

openssl pkey -in private-key.pem -pubout -outform DER \
  | openssl dgst -sha256

Nunca pongas el contenido de private-key.pem, el trazado de comandos ni una variable con la clave en el contexto del agente. Deja que un ejecutor restringido haga la comparación y devuelva resumen y código de salida. El agente necesita el resultado, no el secreto.

Escribir el archivo aún exige activarlo

El despliegue tiene dos operaciones: colocar el material nuevo de forma atómica y hacer que la terminación TLS lo cargue. Los agentes suelen hacer la primera e inferir la segunda. Los servidores duraderos guardan certificados analizados en memoria, así que reemplazar el archivo en disco no cambia necesariamente los nuevos handshakes.

Prepara los archivos junto al destino, fija propietario y permisos restrictivos, valida la configuración y después renómbralos. Un renombrado en el mismo sistema de archivos evita exponer un PEM parcial. Conserva los archivos funcionales anteriores o una referencia versionada hasta que pase la verificación activa; borrarlos de inmediato destruye el rollback más rápido.

La activación depende del terminador. La documentación de nginx dice que HUP hace que el maestro valide la configuración, inicie workers nuevos y retire los antiguos; si falla, nginx sigue con la configuración anterior. Protege la disponibilidad, pero crea un falso positivo perfecto si el agente solo registra que envió HUP. El reinicio graceful de Apache también valida sintaxis e inicia una generación nueva mientras terminan conexiones antiguas. Los balanceadores y CDN gestionados pueden aceptar una actualización y completarla después.

Captura el comando o ID de operación, su estado de salida y la identidad del proceso objetivo. Consulta después el estado o los registros propios del servicio. No conviertas una espera fija en prueba. Dormir 30 segundos unas veces oculta consistencia eventual y otras desperdicia 29; sondear un estado documentado hasta un plazo es más claro.

Un fallo de activación debe parar el flujo antes de que los reintentos públicos carguen el servicio. Si falla la sintaxis, cambia inesperadamente el proceso o el plano de control informa de un error terminal, conserva el certificado anterior y marca el despliegue fallido. Si la activación dice éxito pero el endpoint sigue antiguo, sondea dentro de una ventana limitada porque el reemplazo gradual y la propagación tardan.

Verifica lo que recibe un cliente y su nombre

Cubre emisión y despliegue
Una sesión usa HTTP protegido para emitir y SSH protegido para desplegar.

La comprobación decisiva abre una conexión TLS nueva, envía el Server Name Indication previsto, valida cadena y hostname y registra la hoja. Mirar un archivo local no responde qué recibe el cliente. Reutilizar una conexión keep-alive tampoco, pues el handshake ya eligió certificado.

Usa OpenSSL con SNI y validación de hostname:

openssl s_client \
  -connect api.example.net:443 \
  -servername api.example.net \
  -verify_hostname api.example.net \
  -verify_return_error \
  </dev/null 2>/dev/null \
| openssl x509 -noout -serial -fingerprint -sha256 -dates -issuer

-servername controla SNI y selecciona el host virtual en listeners compartidos. -verify_hostname comprueba identidad y -verify_return_error detiene el comando ante un error en lugar de imprimirlo y seguir. -showcerts muestra la cadena enviada, pero la documentación advierte que esa lista no constituye una cadena validada.

No añadas -k, --insecure ni algo equivalente para hacer pasar la automatización. El manual de curl dice que una petición TLS normal comprueba la confianza de CA y la coincidencia del hostname. Una sonda insegura puede confirmar la huella y omitir la cadena rota o el nombre erróneo que sufrirá el usuario.

Tampoco basta la huella. El servidor puede presentar la hoja esperada con una cadena intermedia incompleta y romper algunos clientes. La barrera debe exigir una ruta de confianza y nombre válidos, además de la identidad esperada. Si la revocación o una política CT forman parte del perfil real, ejecuta ese perfil; la sonda básica no los cubre.

Ejecuta cada observación en un proceso limpio o desactiva la reutilización. Guarda stderr al fallar, pero límpialo antes de pasarlo al agente. Conserva categorías claras: conexión, handshake, confianza, identidad o huella distinta.

Cada terminación TLS es un objetivo separado

Un hostname no define el alcance. Lo define el conjunto de lugares que pueden terminar TLS para él: direcciones de balanceadores, puntos CDN, réplicas ingress, puertas regionales, rutas IPv4 e IPv6 y orígenes directos accesibles. Una conexión correcta prueba una ruta en un instante.

Construye el inventario desde el estado de infraestructura, no desde la respuesta DNS casual de la sonda. DNS dinámico y anycast dificultan una muestra pública exhaustiva, así que define un conjunto defendible: cada listener o asociación de certificado configurados, más sondas desde regiones relevantes. Si un proveedor gestiona el edge, verifica su estado y muestrea externamente desde varias ubicaciones.

Para probar una dirección, --resolve de curl es más seguro que sustituir el hostname por una IP, pues conserva el nombre para SNI y validación:

curl --fail --silent --show-error \
  --resolve api.example.net:443:192.0.2.18 \
  --output /dev/null \
  https://api.example.net/health

Repite para cada dirección, incluidas IPv6 entre corchetes cuando corresponda. Sigue con la sonda OpenSSL a esa dirección manteniendo -servername api.example.net. El HTTP correcto comprueba algo más que TLS, así que usa un endpoint barato y sin mutaciones; la observación del certificado sigue siendo la prueba de cierre.

Aclara los proxies. Una sonda desde un portátil puede ver el certificado de inspección corporativa. Una interna puede saltarse el CDN público. Registra ubicación y ruta, y rechaza la observación si emisor o huella muestran que no llegó al terminador previsto.

Durante un despliegue gradual habrá huellas nuevas y antiguas. Es un estado transitorio válido, no permiso para cerrar por mayoría. Todos los endpoints deben converger o hay que retirar explícitamente el fallido.

Haz que el agente emita registros comparables

Controla cambios de wildcard
Exige Touch ID en cada uso de la credencial que despliega un wildcard.

Un agente debe producir pruebas estructuradas que otro programa compare sin interpretar prosa. Resúmenes como «la renovación funcionó y el sitio se ve bien» borran destinos, tiempos y diferencias. Conserva la explicación humana, pero haz que los estados dependan de campos tipados.

Un par de eventos compacto puede ser:

{"type":"certificate.issued","rotation_id":"rot_7f2","order_id":"ord_91c","dns_names":["api.example.net"],"serial_hex":"03A17C","leaf_sha256":"6B:19:8A:...","spki_sha256":"9f4c...","not_before":"2026-07-24T08:15:00Z","not_after":"2026-10-22T08:14:59Z"}
{"type":"certificate.observed","rotation_id":"rot_7f2","host":"api.example.net","address":"192.0.2.18","port":443,"leaf_sha256":"6B:19:8A:...","chain_valid":true,"name_valid":true,"observed_at":"2026-07-24T08:19:22Z","vantage":"external-us-east"}

Usa un rotation_id en emisión, despliegues, observaciones, reintentos, rollback y cierre. Mantén separados el ID de pedido y el de operación de infraestructura. Un ID genérico dificulta reconstruir incidentes.

Los reintentos necesitan semántica. El agente puede perder la respuesta tras aceptarse un pedido o asociación. Repetir a ciegas crea certificados extra, límites o despliegues rivales. Da a cada mutación un token de idempotencia derivado de la rotación y fase, y consulta la operación remota antes de sustituirla. Registra si la respuesta es nueva o repetida.

La frescura también exige una regla. Una sonda de una hora antes no prueba el despliegue, aunque viera la misma huella en otro intento. Exige que observed_at siga a la activación aceptada y limita la edad al cerrar. Usa el reloj fiable del flujo o del verificador, no una hora escrita por el modelo.

Separa identidad del certificado y del servicio. La huella responde si es la hoja emitida, el hostname si sirve al nombre pedido y la cadena si hay confianza aceptable. Unirlo en tls_ok obliga a repetir pruebas cuando la evidencia ya desapareció.

Versiona también el inventario. Si aparece un listener a mitad de rotación, el cierre debe adoptar la nueva revisión y observarlo o fijarse a la revisión aprobada y abrir seguimiento. Leer una lista móvil crea una carrera. Guarda la revisión para reconstruir qué significaba «todos».

La recogida debe ser repetible: rutas de solo lectura, timeouts cortos y concurrencia limitada. Un health que calienta caché o cambia sesión es mala sonda; TLS ocurre antes del HTTP, así que basta una petición mínima o handshake. Con miles de destinos, programa por objetivo y reintenta solo fallos.

Separa observación de interpretación. La sonda informa bytes y validación; el comparador decide si satisfacen la rotación. Así puedes corregirlo y reprocesar pruebas sin tocar producción, y el agente no puede convertir una diferencia molesta en un resumen tranquilizador.

El comparador debe rechazar observaciones anteriores al despliegue, de host o dirección inesperados o de otra rotación. Debe comparar huellas binarias normalizadas, no su formato visual, pues cambian dos puntos y mayúsculas. Conserva el original para operadores.

No dejes que el agente omita campos. Define el esquema y falla si falta evidencia. Firmar eventos refuerza procedencia, pero no arregla una afirmación débil. «El comando terminó con cero» firmado aún no dice qué certificado recibió el cliente.

Guarda también observaciones fallidas. Una huella distinta, certificado vencido o nombre incorrecto explican por qué quedó abierto y separan propagación lenta de una asociación errónea. Sobrescribir el fallo con éxito elimina la explicación de la ventana de incidente.

El fallo habitual es un despliegue dividido

Empieza sin ruido. El agente obtiene un certificado para api.example.net, registra ACME válido, actualiza api-tls y recibe éxito de la API. Ve una versión nueva del secreto y cierra el ticket.

El hostname resuelve a dos balanceadores. Un controlador vigila api-tls en producción y carga lo nuevo. Otro listener referencia el mismo nombre en un namespace heredado. Ninguna API falla: se actualizó un objeto real, pero no todos los que controlan el nombre.

La mayoría llega al primer destino y ve lo nuevo; otra ruta sirve la hoja anterior. Cerca del vencimiento, los fallos parecen intermitentes y reintentar los cura porque DNS o balanceo cambian el destino. El equipo culpa a cachés aunque TLS elige certificado en cada handshake nuevo.

La doble prueba descubre la división. Emisión dice 6B:19:8A:...; las direcciones devuelven eso y 41:D0:72:.... El estado sigue deployed_unverified y la observación distinta señala qué dirección reparar.

«Míralo en el navegador» es mala recomendación para automatizar. Puede reutilizar conexiones, ocultar dirección, usar otro almacén de confianza o pasar por inspección. Sirve como comprobación independiente en un incidente, pero no para cerrar. Las sondas fijadas por dirección y con hostname validado son repetibles.

Tras corregir la asociación heredada, sondea ambos destinos con conexiones nuevas. Conserva la primera diferencia, la corrección y los éxitos. Esa historia prueba qué cambió y por qué se cerró.

Las acciones privilegiadas necesitan autoridad estrecha

Detén rotaciones al bloquear
El vault bloqueado deniega cada acción de emisión o despliegue.

La rotación toca API de CA, secretos y recargas de producción, por lo que el ejecutor debe exponer acciones concretas, no credenciales. «Enviar este CSR», «asociar la huella X al listener Y» o «sondear H por A» son límites útiles. Dar un token reutilizable al modelo añade riesgo sin mejorar su razonamiento.

Cada resultado debe incluir ID remoto y pruebas, sin credenciales ni clave privada. Separa permisos de emisión, despliegue, verificación y rollback. Poder solicitar un certificado no debe conceder permiso para instalarlo en cualquier sitio.

Sallyport guarda credenciales API y SSH en su vault cifrado mientras el agente ejecuta acciones HTTP y SSH mediante la aplicación, sin recibirlas. Sus diarios Activity y Sessions proceden de un registro cifrado, encadenado por hash y ciego a escritura, adecuado para atribuir llamadas sin fingir que sustituyen la observación del certificado.

Pon aprobación humana donde aumenta el impacto. Una renovación rutinaria para nombre y listener declarados puede usar autorización de sesión; añadir nombre, cambiar clave, tocar wildcard o revertir merece aprobación por llamada. La aprobación debe mostrar objetivo y huella. «Permitir actualizar certificado» no detecta un listener equivocado.

Audita al verificador igual que al desplegador. Si un agente puede cambiar inventario, desplegar y declarar suficiente su muestra incompleta, el contrato es decorativo. Calcula objetivos desde una fuente controlada y rechaza ausencias.

Cierra solo al converger y conserva el rollback

El cierre debe comparar determinísticamente eventos inmutables. No debe preguntar si la rotación «parece lista». Cuando cada endpoint presenta la hoja emitida con cadena y nombre válidos, registra el predicado y cierra.

Define plazos de propagación. Dentro de la ventana, reintenta solo destinos pendientes con espera limitada. Al vencer, falla con los destinos distintos. Revertir depende de validez y salud: un certificado anterior aún válido puede ser más seguro; uno vencido o revocado exige reparar hacia delante.

El rollback necesita la misma prueba. Volver a asociar el artefacto es un intento y hay que observar su huella antes de declarar recuperación. Si la clave fue comprometida, volver a ella no recupera nada: emite con clave nueva y revoca según el plan.

Conserva ambos certificados hasta que el drenaje y la política permitan limpiar. Un reload gradual puede dejar workers antiguos con conexiones existentes, pero sondas nuevas deben llegar a la generación nueva. Borra material anterior por la ruta controlada y registra la limpieza después del cierre, no como condición para servir lo nuevo.

El primer cambio es pequeño y estricto: elimina «certificado descargado» o «secreto actualizado» como éxito final. Exige una huella emitida y huellas nuevas, con hostname validado, de todo el inventario. El agente puede ejecutar cada paso, pero solo las pruebas coincidentes pueden afirmar que terminó.

FAQ

¿Qué demuestra que una rotación TLS tuvo éxito?

Un registro de emisión y una observación activa nueva deben coincidir en la identidad de la hoja. La conexión también debe validar cadena y hostname en cada terminación incluida.

¿Basta una renovación ACME correcta?

No. ACME prueba que la CA emitió y entregó un certificado tras autorizarlo. No prueba que servidor, ingress, balanceador o CDN lo cargue y sirva.

¿Qué campo debe comparar la automatización?

Compara la huella SHA-256 normalizada de la hoja y guarda el serial para lectura humana. El resumen de clave pública distingue si la clave se conservó o rotó.

¿Cómo verifico una dirección concreta del balanceador?

Conecta a ella conservando el hostname para SNI e identidad. Usa curl --resolve o OpenSSL -connect address:port -servername hostname -verify_hostname hostname.

¿Por qué no basta el archivo en disco?

El proceso puede guardar lo anterior en memoria, usar otra ruta o terminar TLS en otro sitio. Solo un handshake nuevo por la ruta real muestra qué se sirve.

¿Debe la sonda omitir la validación TLS?

No. Podría coincidir la huella y ocultar un hostname incorrecto o una cadena rota. Esos fallos afectan al cliente y deben impedir el cierre.

¿Debo verificar cada endpoint CDN o balanceador?

Verifica cada destino configurado que controles y muestrea edges gestionados desde regiones pertinentes. Una respuesta DNS o un edge correcto no prueban convergencia.

¿Certificate Transparency prueba el despliegue?

No. Prueba que un certificado público fue emitido y registrado. No observa qué certificado presenta el servicio.

¿Cuándo debe revertir una rotación automática?

Define plazo y criterios, y revierte solo si el certificado anterior sigue aceptable y reduce riesgo. Verifica la huella servida antes de declarar recuperación.

¿Cómo debe tratar la clave privada un agente?

Debe solicitar acciones restringidas sin recibir bytes de clave ni credenciales reutilizables. Huellas, IDs, estados y errores limpios bastan para razonar sobre pruebas.

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