Límites de confianza
La seguridad de Airframe descansa en unos pocos límites. El código que nadie revisó se ejecuta donde no puede alcanzar nada, el código que aprobaron las personas correctas se ejecuta con identidades que sirven cada una para un solo trabajo, y unos controles en el propio Google Cloud se sostienen aunque se eludiera cada pipeline. Esta página traza esos límites, dice qué hace cumplir cada uno y marca lo que está diseñado pero no construido. Afirmaciones y mecanismos enumera después cada afirmación, una por una.
Los ejemplos vienen de una organización de demostración, un comercio en línea ficticio, cuyos proyectos están todos bajo una carpeta en Google Cloud.
Sin confianza y de confianza
Sección titulada «Sin confianza y de confianza»La plataforma ejecuta sus trabajos de pipeline en dos runners propios, el runner sin confianza y el de confianza, y los mantiene separados.
El runner sin confianza ejecuta el pipeline de cada merge request, y las verificaciones en main que no necesitan identidad, como la validación, el paquete de políticas y las pruebas de la aplicación. Está en el proyecto de integración continua de la plataforma, fuera de los perímetros, en una red propia sin ruta hacia las redes de la plataforma, y sus trabajos no pueden llegar al servidor de metadatos, donde estarían las credenciales de una máquina. Tampoco nada de lo que ejecuta puede obtener una identidad en la nube: cada identidad que un trabajo puede obtener está vinculada a una rama o etiqueta protegida, y el pipeline de un merge request no tiene ninguna de las dos. Así, quien puede subir una rama obtiene un pipeline que no tiene nada.
El runner de confianza está dentro de la red de producción de la plataforma y solo toma los trabajos etiquetados para él, desde refs protegidas. Ahí se ejecutan dos tipos de trabajo: las ejecuciones del ejecutor, y el pipeline en la rama main protegida de cada repositorio después de un merge. Solo ejecuta imágenes del registro propio de la plataforma.
La compuerta entre los dos
Sección titulada «La compuerta entre los dos»La compuerta de aprobación decide cuándo un cambio puede pasar de un lado al otro. Lee el modelo de responsables desde la rama main protegida del catálogo, nunca desde el cambio que juzga, no cuenta ninguna aprobación del autor ni de quien hizo un commit, y da su propia aprobación vinculada al commit que revisó. Solo entonces inicia el ejecutor, con un token de disparo que solo la compuerta tiene, y el ejecutor vuelve a verificar todo antes de tener una credencial.
Una política de aprobación de GitLab hace de la aprobación de la compuerta una condición para el merge en todos los repositorios menos security-policies, que guarda las reglas de aprobación y es la salida cuando la compuerta no puede aprobar. Otra política exige la aprobación de una persona con nombre del catálogo que no escribió el cambio ni hizo commits en él. Hoy una sola persona opera la plataforma, y cada aprobador con nombre es una de las cuentas propias del mantenedor: el mecanismo se aplica, pero la separación entre dos personas todavía no es real. La compuerta de aprobación y el ejecutor explica la secuencia completa.
Las identidades de cada lado
Sección titulada «Las identidades de cada lado»- Antes de un merge, el ejecutor puede usar la identidad de plan de cada producto, que lee y no cambia nada, y cada identidad de apply de no producción, para las vistas previas. No tiene ninguna identidad de apply de producción, así que nada de lo que se ejecuta antes de un merge puede cambiar producción.
- Después de un merge, el trabajo de cada raíz en main protegido obtiene la identidad de apply propia de esa raíz, y ninguna otra. La vinculación nombra la ruta del repositorio, el entorno y la ref protegida, así que un trabajo de otro repositorio, de otro entorno o de una rama sin protección no obtiene nada.
- Las personas tienen roles de lectura, y el equipo de un producto puede agregar una versión de uno de sus secretos de producción, nunca leerla. Cualquier cosa más es una concesión: la de nivel 1, una hora de lectura de un proyecto de no producción, que aprueba quien la pide con un motivo, o una concesión administrativa de hasta dos horas, aprobada por otro miembro del grupo de la plataforma, que hoy es la segunda cuenta del mantenedor.
Tres raíces de la plataforma, las políticas de la organización, la configuración de auditoría y el proveedor de identidades, se aplican en cambio desde una laptop con una concesión, y un plan diario de solo lectura muestra cualquier cambio en ellas como deriva.
La base
Sección titulada «La base»Bajo toda identidad está la base: controles en Google Cloud que se sostienen aunque se eludiera un pipeline, definidos sobre la carpeta de la organización de demostración por la raíz de la organización, y la política de cortafuegos por la raíz de red.
- Políticas de la organización (aplicadas). Prohíben crear o subir claves de cuenta de servicio, las redes predeterminadas, los buckets públicos y las direcciones públicas de Cloud SQL, y exigen Shielded VM y OS Login. Solo los principales de la propia organización pueden aparecer en una política de acceso, solo el runner de confianza puede tener una dirección externa, y los recursos van solo a
us-central1donde un servicio admite la restricción. - Una política de denegación (aplicada). Les niega a todos la creación de claves, los cambios en las políticas de la organización, los cambios en el IAM de la carpeta y cualquier cambio en un sink de registros de la carpeta. Sus únicas excepciones son el grupo de emergencia, la cuenta de administrador del arranque y el propio agente de servicio de Privileged Access Manager, y, solo para el IAM de la carpeta, la identidad que configura las concesiones. Así, un cambio en el acceso a la carpeta existe solo como una concesión registrada y con tiempo limitado.
- Una política de cortafuegos jerárquica (aplicada). El tráfico que entra y sale de las redes de la plataforma se niega por defecto; pasan las API de Google, las verificaciones de estado de los balanceadores de carga y el permiso acotado de cada runner, y el tráfico entre los rangos de la plataforma lo deciden reglas que genera la raíz de red.
- Ningún owner ni editor bajo la carpeta (aplicado). Una restricción personalizada de la política de la organización rechaza una concesión de cualquiera de los dos roles por cualquier camino, la consola incluida, salvo en un proyecto todavía en la ventana de arranque de su fábrica y para el propio agente de servicio de las API de Google, al que Google le da editor cuando se activan las API de un proyecto. Las fábricas de proyectos quitan el rol owner que Google les da en cada proyecto que crean.
- Tres perímetros (diseñados). Los perímetros de VPC Service Controls de producción, no producción y auditoría existen como especificaciones en modo de prueba: registran lo que bloquearían y no bloquean nada. Aplicarlos es una variable, cuando los pipelines propios de la plataforma funcionen sin problemas bajo ellos. Las lecturas diarias de la raíz de la organización que un perímetro rechazaría vienen de dentro del perímetro de producción, del runner de confianza en la VPC de la red de producción, porque la lista de servicios alcanzables desde esa VPC no los incluye.
La base de la arquitectura va más allá de lo construido:
- Binary Authorization para cada servicio (diseñado). La arquitectura la cuenta en la base y la incluye, junto con la política de cortafuegos, entre los permisos de la política de denegación; la política de denegación no cubre ninguna de las dos. Lo construido es una adhesión por servicio: el módulo de Cloud Run del golden path adhiere cada servicio a la política de su proyecto, que en el proyecto de producción de un producto facturado admite solo una imagen que la plataforma construyó y promovió. Un servicio desplegado sin el módulo, como la puerta de enlace de telemetría de la plataforma, se ejecuta sin ella.
Un trabajo diario de Policy Analyzer en el repositorio landing-zone también falla, y genera una alerta, si alguna persona distinta de la única cuenta de administrador, o algún grupo, tiene un rol en la organización.
La cadena de auditoría
Sección titulada «La cadena de auditoría»Cada cambio se puede seguir hasta el merge request, la aprobación y la persona.
Qué se registra. Los registros de auditoría de Google Cloud guardan cada acción administrativa, y los registros de Data Access están activos en la carpeta para los servicios cuyas lecturas importan: Secret Manager, Cloud SQL, Cloud Storage, IAM, Cloud KMS y el intercambio de tokens por el que pasa la identidad de un pipeline. Los propios eventos de auditoría de GitLab, como las aprobaciones, las membresías y la creación de tokens, se transmiten a la compuerta y al receptor de auditoría, un servicio aparte, y cada uno escribe todos los eventos como una línea de registro. GitLab no vuelve a enviar un evento que un destino no pudo recibir, así que el bucket de abajo guarda cada evento dos veces mientras los dos están activos y echa en falta uno solo cuando ninguno de los dos está disponible; un evento que GitLab solo transmite se pierde entonces.
Adónde va. Un único sink agregado en la carpeta envía los registros de auditoría de cada proyecto, y esas líneas de GitLab, a un bucket en el proyecto de auditoría, cifrado con una clave que tiene la plataforma. La política de denegación rechaza cualquier cambio en un sink de la carpeta, así que ni un pipeline ni nadie sin una concesión puede desviar el registro. También protege la política de IAM de la carpeta, que guarda la configuración de auditoría, con una excepción más: la identidad que configura las concesiones, que actúa solo desde código revisado. La condición de esa identidad exige que un cambio modifique al menos una concesión, así que una llamada que cambia únicamente la configuración de auditoría se rechaza. Una llamada que cambia a la vez una concesión permitida y la configuración de auditoría todavía pasa; en la carpeta una regla de Grafana avisa, y en la organización ningún sink la ve.
El sink deja fuera las entradas que VPC Service Controls escribe en modo de prueba, que registran lo que un perímetro habría rechazado y no un rechazo. El registro propio de cada proyecto las conserva, y el bucket bloqueado no las guarda durante un año.
Cuánto tiempo se queda (aplicado). Una política de retención guarda cada objeto durante 365 días, y nadie puede borrarlo ni reemplazarlo antes. La política está bloqueada, lo que Google hace irreversible: nadie, ni un administrador con una concesión, puede acortarla ni quitarla.
Qué la une. La compuerta registra cada veredicto con las afirmaciones del token que lo pidió, el ejecutor registra cada ejecución con su merge request, su commit y su pipeline, un trabajo de plan guarda su plan y el veredicto de las políticas como artefactos que solo los desarrolladores del repositorio pueden leer, y cada entrada del registro de auditoría nombra la identidad que actuó, que responde a un solo repositorio, entorno y ref protegida.
Qué lo vigila (aplicado). Un segundo sink, estrecho, en la carpeta envía a Grafana, a través de la pasarela de registros de producción, las entradas que vigilaría un equipo de seguridad: un intento de crear una clave, un rechazo de una política de denegación o de la organización, un token rechazado, un cambio en los sinks, las políticas de denegación o la configuración de auditoría de la carpeta, una concesión, y los eventos de auditoría de GitLab. Las reglas avisan con urgencia a la plataforma por los cinco primeros y abren un ticket por una concesión o una ráfaga de cambios en GitLab. Un evento en la propia organización, como una concesión a nivel de organización, queda fuera de los sinks de la carpeta.
La arquitectura también diseña un trabajo de auditoría que compara cada acceso con el catálogo; todavía no existe (diseñado).
Dónde está
En el repositorio landing-zone:
- roots/organisation/: las políticas de la organización, la restricción y la política de denegación
- roots/audit/: los sinks, el bucket y los registros de Data Access
- roots/perimeters/: los tres perímetros en modo de prueba
- roots/network/: la política de cortafuegos jerárquica
- docs/guides/security.md: la guía de seguridad de la plataforma
En el repositorio control-plane:
