Compartir a través de


Asegura tus Azure Pipelines

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020

Las canalizaciones ofrecen funcionalidades eficaces para ejecutar scripts e implementar código en entornos de producción, pero es fundamental equilibrar esta potencia con seguridad. Nunca quieres que una canalización termine convirtiéndose en un conducto para código malintencionado. El equilibrio de la seguridad con la flexibilidad y el poder necesarios para los equipos de desarrollo es esencial.

En este artículo se proporciona información general sobre las configuraciones necesarias relacionadas con la seguridad para proteger las canalizaciones frente a amenazas y vulnerabilidades.

Prerrequisitos

Categoría Requisitos
Azure DevOps - Implemente las recomendaciones de Proteger Azure DevOps.
- Conocimientos básicos de YAML y Azure Pipelines. Para más información, consulte Creación de la primera canalización.
Permisos - Para modificar los permisos de canalizaciones: miembro del grupo Administradores de proyectos.
- Para modificar los permisos de la organización: miembro del grupo Administradores de la colección de proyectos.

Restringir el acceso a proyectos, repositorios y conexiones de servicio

Para mejorar la seguridad, considere separar sus proyectos, usar políticas de ramas y añadir más medidas de seguridad para las bifurcaciones. Minimice el ámbito de las conexiones de servicio y use los métodos de autenticación más seguros.

  • Proyectos independientes: administre cada producto y equipo en proyectos independientes. Esto evita que las canalizaciones de un producto accedan accidentalmente a recursos abiertos desde otro producto, lo que minimiza la exposición lateral.
  • Utilice identidades a nivel de proyecto: Utilice una identidad de compilación basada en proyectos para los pipelines en lugar de una identidad a nivel de colección. Las identidades de nivel de proyecto solo pueden acceder a los recursos dentro de su proyecto asociado, lo que minimiza el riesgo de acceso no autorizado por actores malintencionados. Para obtener más información, consulte identidades de compilación de ámbito y ámbito de autorización de trabajos.
  • Usar directivas de rama: para garantizar cambios seguros en el código y la canalización, aplique permisos y directivas de rama. Además, considere la posibilidad de agregar permisos y comprobaciones de canalización a los repositorios.
  • Agregar seguridad adicional para las bifurcaciones: Cuando trabaje con repositorios públicos de GitHub, considere cuidadosamente su enfoque para forks builds. Las bifurcaciones que se originan fuera de su organización plantean riesgos particulares.
    • No proporcionar secretos a las compilaciones de bifurcación: De forma predeterminada, las canalizaciones están configuradas para compilar bifurcaciones, pero los secretos y los recursos protegidos no están disponibles automáticamente para los trabajos de esas canalizaciones de forma predeterminada. Es esencial no deshabilitar esta protección para mantener la seguridad.
    • Considere la posibilidad de desencadenar manualmente compilaciones de bifurcación: desactive las compilaciones automáticas de bifurcación y use comentarios de solicitud de incorporación de cambios para compilar manualmente estas contribuciones. Esta configuración le ofrece la oportunidad de revisar el código antes de desencadenar una compilación. Para obtener más información, consulte Desactivar compilaciones automáticas de 'forks'.
    • No proporcione secretos para las compilaciones de bifurcaciones: De forma predeterminada, los secretos asociados a su canalización no están disponibles para las validaciones de solicitudes de extracción de forks. No habilite la opción Para que los secretos estén disponibles para las compilaciones de bifurcaciones. Para obtener instrucciones sobre cómo encontrar y verificar esta configuración, consulte Contribuciones de bifurcaciones.
    • Considere la posibilidad de desencadenar manualmente compilaciones de bifurcación: desactive las compilaciones automáticas de bifurcación y use comentarios de solicitud de incorporación de cambios para compilar manualmente estas contribuciones. Esta configuración le ofrece la oportunidad de revisar el código antes de desencadenar una compilación. Para obtener instrucciones sobre cómo hacerlo, consulte Desactivar compilaciones automáticas de bifurcación.
    • Usar agentes hospedados por Microsoft para las compilaciones de forks: Evite ejecutar compilaciones de forks en agentes autohospedados. Si lo hace, podría permitir que las organizaciones externas ejecuten código externo en máquinas dentro de la red corporativa. Siempre que sea posible, use agentes hospedados por Microsoft.
    • Utilizar la aplicación Azure Pipelines GitHub para limitar el alcance de los tokens: Cuando construye un GitHub forked pull request, Azure Pipelines se asegura de que el pipeline no pueda cambiar ningún contenido del repositorio de GitHub. Esta restricción solo se aplica si usa la aplicación gitHub de Azure Pipelines para integrarla con GitHub.

Protección de conexiones de servicio

  • Minimizar el ámbito de las conexiones de servicio: las conexiones de servicio solo deben tener acceso a los recursos necesarios. Al crear una nueva conexión de servicio de Azure Resource Manager, elija siempre un grupo de recursos específico. Asegúrese de que el grupo de recursos contiene solo las máquinas virtuales o recursos necesarios para la compilación. Para obtener instrucciones sobre cómo configurar conexiones de servicio, consulte Uso de una conexión de servicio de Azure Resource Manager.
  • Usa la federación de identidades de carga de trabajo para la autenticación: siempre que sea posible, utiliza la federación de identidades de carga de trabajo en lugar de una entidad de servicio para la conexión al servicio de Azure. La federación de identidades de carga de trabajo usa Open ID Connect (OIDC), una tecnología estándar del sector, para facilitar la autenticación entre Azure y Azure DevOps sin depender de secretos. Para obtener instrucciones sobre cómo hacerlo, consulte Creación de una conexión de servicio con la federación de identidades de carga de trabajo (automática).
  • Minimizar el acceso a aplicaciones de GitHub: al configurar la aplicación de GitHub en Azure DevOps, conceda acceso solo a los repositorios que pretende compilar mediante canalizaciones.

Uso de canalizaciones YAML en lugar de canalizaciones clásicas

Para mayor seguridad y para reducir el riesgo de configuraciones incorrectas accidentales, use canalizaciones YAML en lugar de canalizaciones clásicas. Esta precaución evita un problema de seguridad derivado de YAML y canalizaciones clásicas que comparten los mismos recursos, como las conexiones de servicio. Si su organización usa canalizaciones clásicas, migre las canalizaciones a YAML.

  • YAML ofrece las ventajas de la infraestructura como código: trate las canalizaciones de YAML como cualquier otro código, ya que los pasos y las dependencias se definen en el código. También hay una visibilidad clara de las configuraciones de canalización y un riesgo reducido de errores de configuración accidentales.
  • Los pipelines YAML pueden combinarse con medidas de seguridad mejoradas: A través de revisiones de código y pull requests, utilice políticas de rama para establecer un proceso de revisión de pull requests para evitar malas fusiones.
  • Administración de acceso a recursos: los propietarios de recursos controlan si una canalización YAML puede acceder a recursos específicos. Esta característica de seguridad evita ataques como robar otro repositorio. Utilice Aprobaciones y comprobaciones para proporcionar un control de acceso para cada ejecución del pipeline.
    • Comprobación de rama protegida: si tiene procesos de revisión manual de código para ramas específicas, puede ampliar esta protección a las canalizaciones. Una comprobación de rama protegida para un recurso evita que los pipelines se ejecuten automáticamente en ramas no autorizadas.
    • Comprobación de aprobación manual: use una comprobación de aprobación manual para impedir que las solicitudes de canalización usen un recurso protegido hasta que los usuarios o grupos especificados lo aprueben manualmente.
    • Comprobación del horario comercial: use esta comprobación para asegurarse de que una implementación de canalización se inicia dentro de un período de tiempo y día especificados.
  • Desactivar la creación de pipelines clásicos: Desactivar de forma independiente la creación de pipelines de compilación clásicos y pipelines de liberación clásicos. Cuando ambos están deshabilitados, no se puede crear ninguna canalización de compilación clásica, canalización de versión clásica, grupos de tareas o grupos de implementación a través de la interfaz de usuario o la API REST. Para más información, consulte Deshabilitación de la creación de canalizaciones clásicas.

Protección de agentes

Para proteger contenedores, marque volúmenes como de solo lectura, establezca límites de recursos, use imágenes de confianza, busque vulnerabilidades y aplique directivas de seguridad.

  • Utilizar agentes hospedados en Microsoft en lugar de agentes autohospedados: Los agentes hospedados en Microsoft ofrecen aislamiento y una máquina virtual limpia para cada ejecución de un pipeline. Use agentes hospedados por Microsoft en lugar de agentes autohospedados. Para obtener más información, consulte Agentes hospedados por Microsoft.
  • Agentes independientes para cada proyecto: para mitigar el movimiento lateral y evitar la contaminación cruzada entre proyectos, mantenga grupos de agentes independientes, cada uno dedicado a un proyecto específico.
  • Usar cuentas con pocos privilegios para ejecutar agentes: para mejorar la seguridad del sistema, use la cuenta con privilegios más bajos para ejecutar agentes autohospedados. Por ejemplo, considere la posibilidad de usar la cuenta de máquina o una identidad de servicio administrada. No ejecute un agente en una identidad con acceso directo a los recursos de Azure DevOps.
  • Aislar artefactos de producción y grupos de agentes confidenciales: use grupos de agentes diferentes para evitar problemas de seguridad.
    • Utilice un grupo de agentes distinto para los artefactos de producción: aísle los artefactos de producción utilizando un grupo de agentes distinto, evitando despliegues accidentales desde ramas que no son de producción.
    • Segmentación de grupos confidenciales: Cree grupos independientes para cargas de trabajo confidenciales y no sensibles. Permitir solo las credenciales en las definiciones de compilación asociadas al grupo adecuado.
  • Configurar firewalls restrictivos para agentes autohospedados: configure los firewalls para que sean lo más restrictivos posible, al tiempo que permite a los agentes funcionar, equilibrar la seguridad y la facilidad de uso.
  • Actualizar periódicamente los grupos de agentes autohospedados: mantenga actualizados los agentes autohospedados con actualizaciones periódicas para asegurarse de que el código vulnerable no se está ejecutando, lo que reduce el riesgo de explotación.

Uso seguro de variables y parámetros

Use de forma segura variables y parámetros en las canalizaciones siguiendo los procedimientos recomendados para establecer secretos. Las mejores prácticas incluyen la restricción del uso de secretos, el uso de variables de tiempo de cola y la habilitación de la validación de argumentos de tareas de shell para proteger su pipeline de amenazas y vulnerabilidades.

  • Restringir el acceso a secretos: Elimina cualquier secreto o clave que aparezca en los pipelines. Vaya a métodos de autenticación sin secretos, como la federación de identidades de carga de trabajo o establezca secretos en la interfaz de usuario, un grupo de variables o un grupo de variables de origen de Azure Key Vault.
  • Habilitación de la validación de parámetros de shell: cuando la configuración Habilitar la validación de parámetros de tareas de shell está habilitada, hay una comprobación agregada de caracteres como punto y coma, comillas y paréntesis. Active Activar la validación de parámetros de argumentos de tareas de shell a nivel de organización o proyecto en Configuración>Pipelines>Configuración.
  • Limitar variables que se pueden establecer en tiempo de cola: Evite que los usuarios definan nuevas variables en tiempo de cola habilitando el ajuste Limitar variables que se pueden establecer en tiempo de cola en Configuración de la organización>Pipelines>Configuración.
  • Usar parámetros en lugar de variables: a diferencia de las variables, una canalización en ejecución no puede modificar los parámetros de canalización. Los parámetros tienen tipos de datos como number y string, y se pueden restringir a subconjuntos de valores específicos. Esta restricción es valiosa cuando un aspecto configurable por el usuario de la canalización solo debe aceptar valores de una lista predefinida, lo que garantiza que la canalización no acepta datos arbitrarios.
  • Secretos de referencia desde plantillas: en lugar de incluir secuencias de comandos en línea con parámetros secretos directamente en el YAML de su pipeline, utilice plantillas para abstraer la información confidencial fuera de la pipeline principal. Para implementar este enfoque, cree un archivo YAML independiente para el script y, a continuación, almacene ese script en un repositorio seguro independiente. A continuación, puede hacer referencia a la plantilla y pasar una variable secreta en yaML como parámetro. La variable segura debe proceder de Azure Key Vault, un grupo de variables o la interfaz de usuario de canalización. Para más información, consulte Uso de plantillas.
  • Limitar secretos con políticas de rama y permisos de grupo variables: Puede utilizar una combinación de permisos de grupo variables, inserción condicional de trabajos y políticas de rama para asegurarse de que los secretos están vinculados a la rama main. Para obtener más información, consulte Protección de secretos.
  • Usa setvariable para limitar las variables que se pueden establecer: usa el atributo settableVariables para configurar qué variables pueden establecer los autores de canalizaciones en una canalización. Sin esta configuración, los autores de canalizaciones pueden declarar variables nuevas ilimitadas con el setvariable comando de registro. Cuando se especifica una lista with settableVariables vacía, todas las configuraciones de variables están deshabilitadas. Para obtener más información, consulte el settableVariables atributo en el esquema YAML.

El mejor método para proteger un secreto es no tener un secreto en primer lugar. Evite usar secretos siempre que sea posible, no almacenarlos nunca en archivos YAML y asegurarse de que no se registran ni se imprimen para mantener la seguridad.

  • Evite usar secretos siempre que sea posible: compruebe si la canalización puede usar un método diferente al de usar un secreto para realizar una tarea como una conexión de servicio con la federación de identidades de carga de trabajo o una identidad administrada. Las identidades administradas permiten que las aplicaciones y los servicios se autentiquen con Azure sin necesidad de credenciales explícitas. Para obtener más información, consulte Uso de entidades de servicio & identidades administradas. No coloque secretos en YAML: nunca almacene valores confidenciales como texto no cifrado en un archivo de .yml de Azure Pipelines.
  • No registre ni imprima secretos: evite reproducir secretos en la consola, usarlos en parámetros de línea de comandos o registrarlos en archivos. Azure Pipelines intenta depurar los secretos de los registros siempre que sea posible, pero no puede atrapar todas las formas en que se pueden filtrar los secretos.
  • No use datos estructurados como JSON como secretos: cree secretos individuales para cada valor confidencial. Este enfoque garantiza una mejor precisión de la redacción y minimiza el riesgo de exponer datos confidenciales involuntariamente.

Auditoría y rotación de secretos

Para proteger las canalizaciones, audite periódicamente la gestión de secretos en tareas y registros, revise y elimine secretos innecesarios, y rote los secretos para minimizar los riesgos de seguridad.

  • Auditar el manejo de secretos en tareas y registros: comprueba las tareas para asegurarse de que los secretos no se envían a servidores ni se imprimen en los registros. Compruebe que no hay secretos en ningún archivo de registro, incluidos los registros de errores.
  • Revise los secretos registrados: Confirme si los secretos en su canalización aún son necesarios y elimine aquellos que ya no sean necesarios para minimizar el desorden y los posibles riesgos de seguridad.
  • Rotación de secretos: rota periódicamente los secretos para minimizar la ventana de tiempo durante la que se podría aprovechar un secreto en peligro.

Impedir la ejecución de código malintencionado

Para asegurarse de que solo el código probado y saneado se ejecuta a través de la canalización, revise periódicamente las canalizaciones para detectar problemas comunes.

  • Examen de código: escape de caracteres especiales en argumentos para evitar la inyección de comandos del shell. Puede usar GitHub Advanced Security para Azure DevOps para automatizar el análisis de código.
  • Validar entradas y usar parámetros: valide los parámetros y argumentos de entrada para evitar el comportamiento no deseado. Use consultas con parámetros en scripts para evitar la inyección de CÓDIGO SQL. Los parámetros en tiempo de ejecución ayudan a evitar problemas de seguridad relacionados con variables, como la inserción de argumentos.
  • No utilice PATH en scripts: Confiar en la configuración del agente PATH es peligroso porque puede ser alterada por un script o herramienta anterior. En su lugar, utilice siempre una ruta completamente cualificada.
  • Controlar las tareas disponibles: deshabilite la capacidad de instalar y ejecutar tareas desde Marketplace, lo que proporciona un mayor control sobre el código que se ejecuta en una canalización.

Protección de contenedores

Obtenga información sobre cómo proteger los contenedores mediante cambios de configuración, examen y directivas.

  • Marcar volúmenes como solo lectura: Los contenedores incluyen montajes de volúmenes proporcionados por el sistema para tareas, herramientas y componentes externos necesarios para trabajar con el agente anfitrión. Establezca externals, tasks y tools como solo lectura para mayor seguridad.
  • Establecer límites de recursos específicos del contenedor: establezca límites en la CPU y la memoria para evitar que los contenedores consuman recursos excesivos, lo que puede provocar vulnerabilidades de denegación de servicio o seguridad.
  • Uso de imágenes de confianza: use imágenes oficiales y comprobadas de orígenes de reputación, como Azure Container Registry o Docker Hub. Especifique siempre una versión o etiqueta específica para mantener la coherencia y confiabilidad, en lugar de confiar en la etiqueta latest. Actualice periódicamente las imágenes base para incluir las últimas revisiones de seguridad y correcciones de errores.
  • Examinar contenedores para detectar vulnerabilidades y aplicar la protección contra amenazas en tiempo de ejecución: use herramientas como Microsoft Defender for Cloud para supervisar y detectar riesgos de seguridad. Además, Azure Container Registry ofrece un examen de vulnerabilidades integrado para ayudar a garantizar que las imágenes de contenedor sean seguras antes de la implementación. También puede integrar herramientas de análisis de terceros a través de extensiones de Azure DevOps para comprobaciones de seguridad agregadas.
  • Implemente directivas de seguridad para evitar la elevación de privilegios y asegurarse de que los contenedores se ejecutan con la menor cantidad de privilegios necesarios: por ejemplo, Azure Kubernetes Service (AKS),el control de acceso basado en rol y la admisión de seguridad de pod permiten aplicar directivas que restringen los privilegios de contenedor, garantizan la ejecución no raíz y limitan el acceso a recursos críticos.
  • Usar directivas de red: las directivas de red se pueden usar para restringir la comunicación entre contenedores, lo que garantiza que solo los contenedores autorizados puedan acceder a recursos confidenciales dentro de la red. Además, Azure Policy para AKS se puede utilizar para aplicar las mejores prácticas de seguridad de contenedores, como garantizar que solo se implementen imágenes de contenedor de confianza.

Uso de plantillas para aplicar procedimientos recomendados

Comience con una plantilla mínima y aplique gradualmente las extensiones. Este enfoque garantiza que a medida que implemente prácticas de seguridad, tiene un punto de partida centralizado que cubre todas las canalizaciones.

  • Usar plantillas de extensión: las plantillas de extensión definen la estructura externa y ofrecen puntos específicos para las personalizaciones dirigidas. El uso de plantillas de extensión puede impedir que el código malintencionado se infiltra en una canalización.
  • Restringir el acceso con pasos: limite el acceso a la red mediante pasos como la descarga de paquetes que se ejecutan en un contenedor en lugar de en el host. Cuando los pasos se ejecutan en un contenedor, se impide que un actor incorrecto modifique la configuración del agente o deje código malintencionado para su ejecución posterior.