En este documento, se describen las prácticas recomendadas para proteger tus compilaciones. El código de compilación puede hacer referencia a diferentes tipos de operaciones, como las siguientes:
- Optimización o ofuscación del código: Por ejemplo, la herramienta de código abierto de Google Closure Compiler analiza y analiza JavaScript, quita el código inactivo y reescribe y minimiza lo que queda. También verifica el código en busca de errores comunes de JavaScript.
- Compila código en código intermedio: Por ejemplo, puedes compilar código Java en un archivo de clase Java (
.class
) o código C++ en un archivo de objeto (.obj
). - Compilar código y vincular, crear una biblioteca o un archivo ejecutable: por ejemplo, compilar código C++ en una biblioteca compartida (
.so
) o un archivo ejecutable de Windows (.exe
). - Empaquetar código en un formato distribuible o implementable: Los ejemplos incluyen la creación de archivos Java WAR (
.war
) a partir de archivos de clase Java, la creación de una imagen de Docker o la creación de una distribución compilada de Python (.whl
).
Según el lenguaje de programación que uses y el entorno en el que realices la implementación, tu compilación podría contener diferentes combinaciones de estas operaciones. Por ejemplo, una compilación puede empaquetar código de Python en una distribución compilada y subirlo a una tienda de artefactos, como Artifact Registry o PyPI, para que puedas usarlo como dependencia en las funciones de Cloud Run. También puedes crear contenedores para el código de Python y, luego, implementar la imagen del contenedor en Cloud Run o Google Kubernetes Engine.
Las prácticas de este documento se centran en la compilación de código para empaquetar o implementar en entornos de ejecución en lugar de compilar código.
Usa compilaciones automatizadas
Una compilación automatizada o con secuencias de comandos define todos los pasos de compilación en la secuencia de comandos de compilación o la configuración de compilación, incluidos los pasos para recuperar el código fuente y compilar el código. El único comando manual, si corresponde, es el comando para ejecutar la compilación.
Por ejemplo, una secuencia de comandos de compilación puede ser:
- Un
cloudbuild.yaml
de Cloud Build - Un archivo Makefile que ejecutas con la herramienta
make
. - Un archivo de flujo de trabajo de GitHub Actions en formato YAML almacenado en tu directorio
.github/workflows/
.
Las compilaciones automatizadas proporcionan coherencia en los pasos de compilación. Sin embargo, también es importante ejecutar compilaciones en un entorno coherente y confiable.
Aunque las compilaciones locales pueden ser útiles para depurar, lanzar software desde compilaciones locales puede generar muchos problemas de seguridad, inconsistencias y deficiencias en el proceso de compilación.
- Permitir compilaciones locales proporciona una forma para que un atacante con intenciones maliciosas modifíque el proceso de compilación.
- Las inconsistencias en los entornos locales y las prácticas de los desarrolladores dificultan la reproducción de compilaciones y el diagnóstico de problemas de compilación.
Las compilaciones manuales hacen que el proceso sea ineficiente, ya que aprovechan más recursos de infraestructura, como procesamiento, almacenamiento y redes. En los requisitos del framework de SLSA, las compilaciones automatizadas son un requisito para el nivel 1 de SLSA, y usar un servicio de compilación en lugar de entornos de desarrollador para las compilaciones es un requisito para el nivel 2 de SLSA.
Cloud Build es el servicio de compilación administrado en Google Cloud. Usa un archivo de configuración de compilación para proporcionar pasos de compilación a Cloud Build. Puedes configurar compilaciones para recuperar dependencias, ejecutar pruebas de unidades, realizar análisis estáticos y pruebas de integración, y crear artefactos con herramientas de compilación como Docker, Gradle, Maven, Go y Python. Cloud Build está completamente integrado en otros servicios de CI/CD en Google Cloud, como Artifact Registry y Cloud Deploy, así como en entornos de ejecución, como GKE y Cloud Run. También proporciona integración con los principales sistemas de administración de código fuente, como GitHub y Bitbucket.
Genera la procedencia de la compilación
La proveniencia de la compilación es una colección de datos verificables sobre una compilación.
Los metadatos de procedencia incluyen detalles como los resúmenes de las imágenes compiladas, las ubicaciones de la fuente de entrada, la cadena de herramientas de compilación y la duración de la compilación.
Generar la procedencia de la compilación te ayuda a hacer lo siguiente:
- Verifica que un artefacto compilado se haya creado desde una ubicación de fuente confiable y con un sistema de compilación confiable.
- Identifica el código insertado desde una ubicación de fuente o un sistema de compilación no confiables.
Puedes usar mecanismos de alertas y políticas para usar de forma proactiva los datos de procedencia de la compilación. Por ejemplo, puedes crear políticas que solo permitan implementaciones de código compilado a partir de fuentes verificadas.
Para el nivel 1 de SLSA, la procedencia de la compilación debe estar disponible para los consumidores de los artefactos compilados. Para el nivel 2 de SLSA, los datos de procedencia de la compilación también deben cumplir con los siguientes requisitos:
- Se genera con el servicio de compilación o se puede leer directamente desde él.
- Un consumidor puede verificar la autenticidad y la integridad. Esto se debe hacer con una firma digital generada por el servicio que crea los datos de procedencia de la compilación.
Para el nivel 3 de la SLSA, el contenido de la procedencia también debe incluir lo siguiente:
- Es el punto de entrada de la definición de compilación.
- Todos los parámetros de compilación están bajo el control de un usuario.
Cloud Build puede generar la procedencia de compilaciones para imágenes de contenedores que proporcionan garantías de compilación de SLSA de nivel 3. Para obtener más información, consulta Cómo ver la procedencia de la compilación.
Usa un entorno de compilación efímero
Los entornos efímeros son entornos temporales que están diseñados para durar una sola invocación de compilación. Después de la compilación, se borra o se limpia el entorno. Las compilaciones efímeras garantizan que el servicio de compilación y los pasos de compilación se ejecuten en un entorno efímero, como un contenedor o una VM. En lugar de reutilizar un entorno de compilación existente, el servicio de compilación aprovisiona un entorno nuevo para cada compilación y, luego, lo destruye después de que se completa el proceso de compilación.
Los entornos efímeros garantizan compilaciones limpias, ya que no hay archivos residuales ni parámetros de configuración del entorno de compilaciones anteriores que puedan interferir en el proceso de compilación. Un entorno no efímero brinda la oportunidad a los atacantes de insertar archivos y contenido maliciosos. Un entorno efímero también reduce la sobrecarga de mantenimiento y las inconsistencias en el entorno de compilación.
Cloud Build configura un nuevo entorno de máquina virtual para cada compilación y lo destruye después de la compilación.
Restringe el acceso al servicio de compilación
Sigue el principio de seguridad de privilegio mínimo otorgando los permisos mínimos necesarios al servicio de compilación y a los recursos de compilación. También debes usar una identidad no humana para ejecutar compilaciones y, en su nombre, interactuar con otros servicios.
Si usas Cloud Build, haz lo siguiente:
- Otorga los permisos mínimos requeridos a los miembros de tu organización.
- Personaliza los permisos de la cuenta de servicio que actúa en nombre de Cloud Build para que solo tenga los permisos necesarios para tu uso. Edita los permisos de la cuenta de servicio predeterminada de Cloud Build o considera usar una cuenta de servicio personalizada en su lugar.
- Usa la política de la organización Integraciones permitidas de Cloud Build para controlar los servicios externos que pueden invocar activadores de compilación.
Coloca Cloud Build en un perímetro de servicio con los Controles del servicio de VPC. El perímetro permite la comunicación libre entre los servicios de Google Cloud dentro del perímetro, pero limita la comunicación en todo el perímetro según las reglas que especifiques. El perímetro también mitiga el riesgo de robo de datos.
Cloud Build solo admite los Controles del servicio de VPC para las compilaciones que se ejecutan en un grupo privado.
Protege las credenciales
Las compilaciones suelen incluir conexiones a otros sistemas, como el control de versión, los almacenes de artefactos y los entornos de implementación. Proteger las credenciales que usas en tus compilaciones ayuda a evitar el acceso no autorizado a los sistemas de tu cadena de suministro de software y el robo de datos.
Evita almacenar credenciales hard-coded directamente en el control de versión o en la configuración de compilación. En su lugar, almacena las credenciales en un almacén de claves seguro.
En Google Cloud, Secret Manager almacena de forma segura claves de API, contraseñas y otros datos sensibles. Puedes configurar Cloud Build para usar secretos almacenados en Secret Manager.
Administra tus dependencias
La integridad de tus aplicaciones depende de la integridad del código que desarrollas y de las dependencias que usas. También debes considerar dónde publicas tus dependencias, quién tiene acceso para leer y escribir en tus repositorios de artefactos, y las políticas para fuentes de confianza de artefactos de compilación que implementas en tus entornos de ejecución.
Para obtener más información sobre la administración de dependencias, consulta Cómo administrar dependencias.
En Cloud Build, usas compiladores en la nube para ejecutar comandos. Los generadores son imágenes de contenedor con lenguajes comunes y herramientas instaladas. Puedes usar imágenes de contenedores públicas de registros públicos, como Docker Hub, compiladores proporcionados por Cloud Build, compiladores que contribuyen con la comunidad y compiladores personalizados que creas. También puedes usar buildpacks como compiladores, incluidos los paquetes de compilación de Google Cloud.
Revisa los generadores que usas en tus compilaciones de Cloud Build, averigua quién los proporciona y decide si confías en ellos en tu cadena de suministro de software. Para mantener un mayor control sobre el código de un compilador, puedes crear compiladores personalizados en lugar de usar compiladores de una fuente pública.
Reduce las oportunidades de alterar la compilación
Existen varios otros factores que pueden influir en una compilación, incluidos los siguientes:
- Compilaciones que se ejecutan de forma simultánea y pueden influir entre sí, o una compilación que persiste y afecta a una compilación posterior
- Compilaciones que aceptan parámetros de usuario distintos del punto de entrada de la compilación y la ubicación de la fuente de nivel superior.
- Compilaciones que especifican dependencias con rangos o dependencias que son mutables (por ejemplo, usar una imagen con la etiqueta
latest
) Estos enfoques crean el riesgo de que las compilaciones usen versiones incorrectas o no deseadas de las dependencias.
Las siguientes prácticas ayudan a mitigar estos riesgos:
- Ejecuta cada compilación en un entorno efímero.
- Evita ejecutar compilaciones con parámetros adicionales para que los usuarios no puedan influir en las variables definidas en las secuencias de comandos de compilación.
- Restringe el acceso al servicio de compilación y a los recursos de compilación.
- Consulta versiones inmutables de dependencias en lugar de identificadores, como etiquetas que pueden apuntar a una versión diferente del artefacto en el futuro. Para obtener más información sobre las dependencias, consulta Administración de dependencias.
Seguridad de la cadena de suministro del software
Google Cloud proporciona un conjunto de herramientas y capacidades modulares que puedes usar para mejorar la postura de seguridad de tus cadenas de suministro de software. Muestra estadísticas de seguridad para las aplicaciones compiladas por Cloud Build. Esto incluye lo siguiente:
- El nivel de SLSA, que identifica el nivel de madurez de la seguridad de tu cadena de suministro de software
- Declaraciones de vulnerabilidades, lista de materiales de software (SBOM) y Vulnerability Exploitability eXchange (VEX) para artefactos de compilación
- La procedencia de la compilación, que es una colección de metadatos verificables sobre una compilación Incluye detalles como los resúmenes de las imágenes compiladas, las ubicaciones de la fuente de entrada, la cadena de herramientas de compilación, los pasos de compilación y la duración de la compilación.
Si deseas obtener instrucciones para ver las estadísticas de seguridad de las aplicaciones compiladas, consulta Compila una aplicación y consulta las estadísticas de seguridad.
¿Qué sigue?
- Conoce las prácticas recomendadas para proteger el código fuente.
- Conoce las prácticas recomendadas para proteger las dependencias.
- Conoce las prácticas recomendadas para proteger las implementaciones.