Protección de repositorios y canalizaciones

Completado

Al usar la automatización para implementar la infraestructura, la canalización y el repositorio se vuelven potentes e importantes. Esto se debe a que ahora representan la única forma de aplicar los cambios a los entornos controlados.

Muchas partes de la organización de Azure DevOps, el repositorio de GitHub y las canalizaciones deben protegerse. En la tabla siguiente se proporcionan algunos de los elementos más importantes que debe proteger, junto con ejemplos de vulnerabilidades que pueden producirse si no los protege adecuadamente.

Elemento que se debe proteger Ejemplo de vulnerabilidad
Su organización de Azure DevOps o repositorio de GitHub, incluido quién tiene acceso a ella y qué puede hacer. Un exempleado descontento elimina el repositorio de código.
Ramas importantes en su repositorio y el proceso que debe tener lugar para cambiar el código en esas ramas. Alguien confirma accidentalmente algún código de Bicep no seguro en la rama principal del repositorio.
El código del repositorio, incluidas las definiciones de infraestructura, las pruebas y el código de aplicación. Alguien se olvida de probar el código que acaba de escribir y no funciona correctamente cuando se publica en producción.
La definición de la canalización. Alguien agrega sin darse cuenta un paso de canalización que escribe una cadena de conexión de base de datos en el registro de la canalización.
Los agentes o los ejecutores que ejecutan la canalización. Una canalización que se ejecuta en una solicitud de incorporación de cambios de borrador instala una vulnerabilidad de seguridad en el agente, que se usa más adelante para una implementación de producción.
Cualquier tarea o componente de terceros que pueda ejecutarse dentro de la canalización. Una tarea de canalización de terceros envía las credenciales de la entidad de servicio a un sitio web malintencionado.
Las entidades de servicio que usa la canalización para obtener acceso a Azure. Una entidad de servicio que no es de producción realiza accidentalmente un cambio en el entorno de producción.
Los secretos que usa la canalización para acceder a sistemas externos. Un miembro del equipo escribe un nuevo archivo de definición de canalización para un prototipo y lo conecta accidentalmente a su entorno de producción.

Ahora aprendamos sobre algunos de los enfoques que puede usar para aplicar gobernanza y controles entorno a su repositorio de código y sus canalizaciones de implementación, tanto en Azure DevOps como en GitHub.

Administrar usuarios y permisos

Tenga en cuenta cómo concede acceso a su organización de Azure DevOps o repositorio de GitHub. Piense en quién tiene acceso y qué puede hacer.

Se recomienda usar la instancia de Microsoft Entra de su organización como proveedor de identidades de la canalización. De esa manera, puede asegurarse de que siempre que alguien se una o abandone la organización, el acceso a la canalización se concederá o revocará automáticamente. Al utilizar Microsoft Entra ID, también puede implementar fácilmente protecciones como el acceso condicional y la autenticación multifactor.

Nota:

Para usar la integración de Microsoft Entra con GitHub, su organización necesita una licencia de GitHub Enterprise.

También puede crear equipos (en GitHub) o grupos (en Azure DevOps), que representen conjuntos de usuarios a los que se pueden conceder permisos conjuntamente. De esta forma, no será necesario asignar permisos individualmente. Es fácil cambiar los permisos de los usuarios, solo tiene que agregarlos y quitarlos de un equipo o grupo.

Sugerencia

Azure DevOps usa un modelo de permisos de privilegios mínimos, que es diferente del modelo que usa Azure. En Azure DevOps, los permisos denegados anulan los permisos permitidos. Esto significa que si se le asignan varios grupos con diferentes conjuntos de permisos, solo podrá realizar las acciones permitidas por todos los grupos.

Asegúrese de que comprende cómo se asignan los permisos, especialmente cuando se trata de grupos.

Protección de ramas de código importantes

Las canalizaciones y la automatización deben basarse en la identificación de ramas de código específicas, como la principal. El código de estas ramas designadas suele ser de confianza y se permite su implementación en los entornos de producción. Aplique controles para asegurarse de que se ha comprobado y revisado el código que se encuentra en sus ramas importantes.

Considere la posibilidad de usar reglas de protección de ramas (en GitHub) o directivas de rama (en Azure Repos) para evitar confirmaciones directas en ramas de código importantes. A continuación, puede requerir que el equipo use solicitudes de incorporación de cambios para combinar los cambios. Puede aplicar comprobaciones automatizadas y procesos de revisión manual para comprobar que los cambios sean válidos antes de combinarlos.

Prueba y revisión del código

Asegúrese de que su equipo comprenda sus expectativas de revisar y probar todo el código, incluidas las definiciones de la infraestructura.

Las definiciones de canalizaciones son archivos YAML, por lo que son una forma de código. Los cambios en las definiciones de canalizaciones deben revisarse y evaluarse. De lo contrario, alguien podría crear accidental o malintencionadamente un paso de canalización que filtre las credenciales de su entidad de servicio o realice un cambio peligroso en su propiedad de Azure.

Los cambios realizados en los archivos de definición de canalizaciones deben revisarse a fondo. Asegúrese de que todos los miembros de su equipo comprendan que las canalizaciones contienen muchos privilegios y necesitan atención especial.

Protección de agentes y ejecutores de canalización

La canalización se ejecuta en agentes (para Azure Pipelines) o ejecutores (para Acciones de GitHub). Puede pensar en los agentes y ejecutores como máquinas virtuales. La definición de canalización controla esas máquinas virtuales ejecutando las tareas y scripts que usted ha proporcionado.

Tanto Azure Pipelines como Acciones de GitHub proporcionan agentes y ejecutores hospedados que Microsoft o GitHub configura y mantiene. El propietario de la plataforma configura los equipos para que cumplan con las prácticas de seguridad recomendadas. Entre las responsabilidades del propietario de la plataforma se incluyen aplicar parches a vulnerabilidades del sistema operativo.

También puede elegir usar sus propias máquinas físicas o virtuales para los agentes y ejecutores. Las máquinas de este tipo se denominan agentes autohospedados y ejecutores. Si usa agentes autohospedados y ejecutores, será su responsabilidad asegurarse de que las máquinas estén configuradas correctamente y protegidas frente a amenazas.

Los agentes hospedados en Microsoft y los ejecutores hospedados en GitHub son efímeros. Los cambios de archivos o configuración a un agente o ejecutor se destruyen cuando finaliza la ejecución de una canalización. Si hospeda internamente el agente o el ejecutor, es probable que se use la misma máquina para varias canalizaciones o entornos independientes, incluidos entornos de producción y de no producción. Supongamos que alguien crea una definición de canalización que modifica algunos archivos importantes en el sistema operativo del agente y ejecuta la canalización desde una solicitud de incorporación de cambios. La próxima vez que se ejecute una implementación en el entorno de producción, se podría volver a usar el agente. Ahora no tiene manera de predecir cuál puede ser el impacto del archivo dañado en su entorno de producción.

Por este motivo, se recomienda usar agentes hospedados en Microsoft y ejecutores hospedados en GitHub siempre que sea posible. Si necesita utilizar ejecutores hospedados internamente, evalúe cuidadosamente los riesgos relacionados con su configuración y uso.

Evaluación de componentes de terceros que se ejecutan dentro de la canalización

Si usa extensiones de Acciones de GitHub o Azure DevOps proporcionadas por la comunidad, infórmese de quién las creó y qué hacen. Los componentes de canalización de terceros pueden tener acceso a las credenciales de la entidad de servicio y, por tanto, a todo el entorno de Azure.

En Azure DevOps, el administrador de la organización suele aprobar todas las extensiones para que se puedan usar. Si es el administrador de la organización, tenga en cuenta el riesgo de seguridad de cada componente que use. Es el responsable de comprobar que sean confiables y seguros.

Siempre que use una acción o tarea de terceros, especifique la versión. Considere la posibilidad de especificar la versión exacta que ha revisado. Permitir que la canalización use automáticamente una versión posterior podría suponer un riesgo que no ha revisado.

Protección de la entidad de servicio de la canalización

Las canalizaciones usan entidades de servicio para obtener acceso a Azure y otros servicios. Es importante proteger las entidades de servicio y asegurarse de que sus credenciales no se puedan usar de forma inadecuada. Considere la posibilidad de aplicar varias capas de protección.

En primer lugar, puede considerar la posibilidad de proteger las credenciales de las entidades de servicio:

  • Siempre que sea posible, use identidades administradas o identidades de carga de trabajo para evitar almacenar las credenciales en su totalidad. Aunque no puede usar identidades administradas o identidades de carga de trabajo con todas las canalizaciones, se recomienda hacerlo siempre que sea posible.
  • Planee cómo va a cambiar o renovar las credenciales de su entidad de servicio con frecuencia. Por ejemplo, es posible que su organización tenga una directiva para renovar las credenciales cada 90 o 120 días. Piense en quién será responsable de la renovación y cómo actualizará todos los lugares donde se usa la credencial.
  • Considere la posibilidad de designar un custodio de secretos cuyo rol sea administrar secretos, claves y certificados para que no se expongan a otras partes de la organización.

A continuación, piense en los permisos que concede a las entidades de servicio:

  • Aplique directivas de acceso condicional de Microsoft Entra a las entidades de servicio de la canalización. Estas directivas ayudan a identificar los inicios de sesión y comportamientos arriesgados. Por ejemplo, si las entidades de servicio de canalización siempre inician sesión desde una sola región geográfica, la función de acceso condicional puede detectar e impedir inicios de sesión desde ubicaciones inesperadas, lo que podría indicar que las credenciales se han visto expuestas.
  • Piense detenidamente en los permisos que concede a cada entidad de servicio. Por ejemplo, supongamos que tiene una entidad de servicio que usa para leer la configuración de un recurso compartido. Considere si puede conceder acceso de solo lectura a esa entidad de servicio, ya que no se tiene que hacer nada desde ahí que requiera más privilegios.
  • Use el ámbito mínimo para cada permiso que asigne a una entidad de servicio. Por ejemplo, si la entidad de servicio necesita implementar en un único grupo de recursos, en ese caso se aplica el ámbito de la asignación de roles a ese grupo de recursos en lugar de a toda la suscripción.
  • Use entidades de servicio independientes para cada uno de los entornos. De este modo, incluso si las credenciales de una entidad de servicio están comprometidas o si alguien obtiene acceso a un entorno, no podrá acceder a otros entornos.

Protección de las conexiones y los secretos del servicio

Las conexiones de servicio (en Azure Pipelines) o los secretos (en GitHub) contienen las credenciales de la entidad de servicio que usa la canalización para obtener acceso a su entorno de Azure. Es importante que proteja las conexiones y los secretos del servicio, y que controle qué canalizaciones usan cada conexión y secreto del servicio. En caso contrario, puede permitir accidentalmente un entorno que no sea de producción usar una entidad de servicio que tiene acceso a los recursos de producción.

En Azure DevOps, al crear una conexión de servicio, puede configurarla para que requiera su aprobación antes de que se pueda usar en una nueva canalización o un nuevo entorno.

Azure DevOps también le permite asociar comprobaciones con conexiones de servicio específicas. Las comprobaciones agregan otro nivel de protección. Por ejemplo, puede configurar una comprobación en una conexión de servicio de producción para comprobar que solo se usa en el código de la rama principal del repositorio. Esta comprobación ayuda a evitar que se implemente código no autorizado en su entorno de producción.

En GitHub, puede configurar secretos específicos del entorno para que, cuando el flujo de trabajo de Acciones de GitHub trabaje con ese entorno, solo proporcione el valor del secreto. Mediante el uso de secretos específicos del entorno y controles de entorno como aprobaciones, puede reducir el riesgo de que se use una implementación de no producción para realizar implementaciones en el entorno de producción. También puede usar identidades de carga de trabajo para evitar el uso de credenciales en los flujos de trabajo de Acciones de GitHub y eliminar la posibilidad de que las credenciales puedan verse expuestas.

Uso de las características de seguridad de GitHub

GitHub proporciona características de seguridad que debe evaluar y usar. Entre ellas se incluyen:

  • Dependabot, que analiza las dependencias del código fuente en busca de vulnerabilidades conocidas.
  • Análisis de secretos, que identifica texto en el repositorio que se parece a claves o credenciales. Almacenar secretos en un repositorio es una práctica no recomendada. Si se le alerta de un secreto en el repositorio, debe considerar que el valor del secreto está en peligro y revocarlo o cambiarlo.
  • Auditoría, que le permite saber quién ha realizado cambios en la configuración de GitHub.
  • Información general de seguridad, que consolida todas las alertas de seguridad en los repositorios de su organización.

Uso de registros de auditoría de Azure DevOps

Azure DevOps proporciona registros de auditoría para ayudarle a saber quién ha realizado cambios en sus canalizaciones, directivas de ramas, repositorios y otros recursos. Se recomienda habilitar la auditoría y revisar los registros de auditoría periódicamente.

Protección del repositorio y la canalización

Hemos analizado los controles importantes que puede aplicar al repositorio y a la canalización. Ahora vamos a considerar qué controles podría usar para proteger cada uno de los elementos importantes que se han enumerado anteriormente en esta unidad:

Elemento que se debe proteger Controles para aplicar
Su organización de Azure DevOps o repositorio de GitHub, incluido quién tiene acceso a ella y qué puede hacer.
  • Use Microsoft Entra ID para la autenticación.
  • Use equipos y grupos para asignar permisos.
  • Habilite el registro de auditoría y revise los registros de auditoría periódicamente.
Ramas importantes en su repositorio y el proceso que debe tener lugar para cambiar el código en esas ramas. Aplique reglas de protección de ramas o directivas de rama.
El código del repositorio, incluidas las definiciones de infraestructura, las pruebas y el código de aplicación.
  • Aplique los requisitos de revisión de código.
  • Agregue pruebas manuales o automatizadas.
  • En GitHub, utilice Dependabot y el análisis de secretos.
La definición de la canalización. Aplique los requisitos de revisión de código.
Los agentes o los ejecutores que ejecutan la canalización.
  • En Azure Pipelines, use agentes hospedados en Microsoft.
  • En Acciones de GitHub, use ejecutores hospedados en GitHub.
Cualquier tarea o componente de terceros que pueda ejecutarse dentro de la canalización. Revise el riesgo de seguridad asociado con todas las extensiones y tareas de terceros.
Las entidades de servicio que usa la canalización para obtener acceso a Azure.
  • Use identidades de carga de trabajo en Acciones de GitHub. Para Azure Pipelines, use las entidades de servicio y renueve periódicamente sus credenciales.
  • Use entidades de servicio independientes para cada uno de los entornos.
  • Aplique directivas de acceso condicional.
Los secretos que usa la canalización para acceder a sistemas externos.
  • En Azure DevOps, use aprobaciones y comprobaciones en las conexiones de servicio.
  • En GitHub, use secretos específicos del entorno e identidades de carga de trabajo.