Reglas de políticas
El paquete de políticas son las reglas de la plataforma escritas como código, y esta página enumera cada una de ellas: lo que comprueba, si detiene un cambio o solo advierte, y lo que su mensaje te indica hacer en su lugar. Cuando un merge request falla por una regla, búscala aquí, lee la alternativa y cambia el código para que coincida.
La página de políticas como código explica dónde se ejecutan las reglas y qué hacen sus dos veredictos. En resumen, las mismas reglas se ejecutan con airframe validate en una laptop, en la validación del merge request, en las ejecuciones del ejecutor al aprobar, y en policy:<root> sobre el plan antes de cada apply.
Cómo leer una fila
Sección titulada «Cómo leer una fila»Cada fila es una regla, con tres datos y una fuente:
- Nivel es uno de tres:
- rechazo (deny): el job falla, y GitLab fusiona un merge request solo cuando su pipeline pasa (aplicado).
- advertencia (warn): el job muestra el hallazgo y pasa. El diseño pide la aprobación de la plataforma para cada advertencia; esa aprobación está diseñada, así que hoy una advertencia no detiene nada.
- advertencia en esta versión, rechazo en la siguiente: una regla nueva que primero advierte, para que los equipos puedan corregir lo que rechazaría. Que después pase a rechazar es una convención: nada cambia el nivel por sí solo, y algunas reglas marcadas así siguen siendo advertencias.
- Qué comprueba dice qué mira la regla. En el código de Terraform el paquete juzga solo los valores escritos de forma literal; en el plan ve cada valor.
- Qué indica su mensaje es la alternativa conforme que nombra el mensaje, cuando nombra una.
- Fuente es el archivo del paquete que contiene la regla. La lista propia del paquete es
docs/policy-pack.md; una regla cuya fuente dice que no está listada allí está en el código pero falta en esa lista.
Las tablas describen el paquete en la versión de la plataforma 2026.10.01-1, cuyo commit de control-plane es c53c0bc.
Identidad y acceso
Sección titulada «Identidad y acceso»Ningún principal público
- Nivel
- Rechazo
- Qué comprueba
- Una concesión a
allUsersoallAuthenticatedUsersen cualquier miembro, vínculo o política de IAM. - Qué indica su mensaje
- Exponer el servicio mediante el ingreso externo detrás de IAP, que está diseñado; el camino construido es una ruta en el borde compartido, detrás del inicio de sesión único.
- Fuente
- control-plane
policy/airframe/iam.rego
Ningún rol de propietario o editor
- Nivel
- Rechazo
- Qué comprueba
- Los roles
roles/owneryroles/editor, en cualquier forma de IAM. El rol de lector está permitido: es la lectura permanente prevista en el diseño. - Qué indica su mensaje
- Otorgar un rol predefinido o personalizado.
- Fuente
- control-plane
policy/airframe/iam.rego
Ninguna clave de cuenta de servicio
- Nivel
- Rechazo
- Qué comprueba
- Cualquier recurso de clave de cuenta de servicio.
- Qué indica su mensaje
- Usar la federación de identidades de carga de trabajo.
- Fuente
- control-plane
policy/airframe/iam.rego
Ninguna administración de IAM para un miembro no listado
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Un rol que administra IAM, como Project IAM Admin, otorgado en un proyecto, una carpeta o la organización a un miembro que el paquete no lista para él.
- Qué indica su mensaje
- Ninguna: los roles de una raíz son el alcance que declara su README, nunca la administración de IAM.
- Fuente
- control-plane
policy/airframe/iam.rego,input.rego; no está listada endocs/policy-pack.md
Nombres, etiquetas y región
Sección titulada «Nombres, etiquetas y región»Las etiquetas de la plataforma
- Nivel
- Rechazo
- Qué comprueba
- Un recurso que declara etiquetas debe llevar
managed_by,tenant,domain,product,envycriticality. Las claves de KMS, los secretos de Secret Manager y los grupos de Cloud Identity están exentos. - Qué indica su mensaje
- El mensaje enumera las etiquetas que faltan. Los módulos del golden path las ponen todas.
- Fuente
- control-plane
policy/airframe/naming.rego
Los identificadores de proyecto siguen las reglas de nombres
- Nivel
- Rechazo
- Qué comprueba
- Un identificador de proyecto escrito debe ser el de un producto,
lk-<domain>-<product>[-np]-<rnd>, el de un proyecto de la plataforma o el de un playground. - Qué indica su mensaje
- Las reglas de nombres de los contratos, sección 2.
- Fuente
- control-plane
policy/airframe/naming.rego
Un recurso suelto necesita una razón
- Nivel
- Advertencia
- Qué comprueba
- Cada recurso que una raíz de producto declara por sí misma en lugar de hacerlo con un módulo del golden path.
- Qué indica su mensaje
- Dar una razón en el merge request, y usar los módulos del golden path cuando uno cubre el recurso.
- Fuente
- control-plane
policy/airframe/naming.rego
El nombre de un recurso suelto empieza con el del producto
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Un recurso suelto cuyo nombre no empieza con su etiqueta
producty un guion. - Qué indica su mensaje
- Empezar el nombre con el slug del producto, como dicen las reglas de nombres de los contratos.
- Fuente
- control-plane
policy/airframe/naming.rego
Una sola región
- Nivel
- Rechazo
- Qué comprueba
- Cualquier región o ubicación escrita que no sea
us-central1, una zona dentro de ella, oglobal. - Qué indica su mensaje
- La región de la plataforma,
us-central1, que el mensaje nombra. - Fuente
- control-plane
policy/airframe/naming.rego
Ningún identificador ni número de proyecto escrito en el código
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Fuera de las fábricas de proyectos, cualquier texto con la forma de un identificador o de un número de proyecto, salvo los del proyecto de arranque y los nombres de buckets de la plataforma con la misma forma.
- Qué indica su mensaje
- Tomar el proyecto de las salidas de la fábrica o de la salida Ready del producto, porque un proyecto reconstruido cambia ambos.
- Fuente
- control-plane
policy/airframe/literal_ids.rego; no está listada endocs/policy-pack.md
Código de Terraform
Sección titulada «Código de Terraform»Ningún programa externo, lectura web ni script de aprovisionamiento
- Nivel
- Rechazo
- Qué comprueba
- La fuente de datos
external; una fuente de datoshttphacia una dirección que no está en la lista permitida, que está vacía; y un script de aprovisionamiento en cualquier recurso. - Qué indica su mensaje
- Ninguna.
- Fuente
- control-plane
policy/airframe/code.rego,data.json
Proveedores permitidos y una versión de Terraform fijada
- Nivel
- Rechazo
- Qué comprueba
- En el código, un proveedor de fuera de los espacios de nombres permitidos (
hashicorp/,gitlabhq/,grafana/,integrations/), y una raíz sinrequired_version. Quebackend.tfcontenga solo el backend está en la lista del paquete, pero ninguna regla lo comprueba, así que esa parte está diseñada. - Qué indica su mensaje
- Fijar la versión de Terraform de la plataforma.
- Fuente
- control-plane
policy/airframe/code.rego,data.json
Estado remoto solo entre pares declarados
- Nivel
- Rechazo
- Qué comprueba
- En una raíz de producto, leer el estado de otra raíz, salvo una raíz de vista previa que lee el estado de no producción de su producto.
- Qué indica su mensaje
- Nada más que la regla: leer estado es solo para los pares de productor y consumidor declarados.
- Fuente
- control-plane
policy/airframe/code.rego,data.json
Servicios y datos
Sección titulada «Servicios y datos»Ingreso solo con inicio de sesión único o por el borde
- Nivel
- Rechazo
- Qué comprueba
- Un servicio de Cloud Run abierto a todo el tráfico sin IAP, salvo que sea el servicio de una vista previa o un servicio de la plataforma con nombre que se autentica solo; y el ingreso solo por balanceador en un servicio que no está en el borde compartido ni registrado para ingreso externo.
- Qué indica su mensaje
- A una vista previa se llega a través de su enrutador con la comprobación de invocador activa; los demás servicios van al borde compartido.
- Fuente
- control-plane
policy/airframe/cloud_run.rego
La comprobación de invocador sigue activa
- Nivel
- Rechazo
- Qué comprueba
- Un servicio de Cloud Run con su comprobación de invocador apagada, salvo un servicio con nombre que se autentica solo en una raíz de la plataforma o un servicio en el borde compartido.
- Qué indica su mensaje
- Solo los servicios con nombre que se autentican solos, hoy la compuerta de aprobación y el gateway de telemetría, o un servicio en el borde pueden desactivarla.
- Fuente
- control-plane
policy/airframe/cloud_run.rego,data.json
Un servicio del borde conserva su comprobación de invocador
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Un servicio en el borde compartido con su comprobación de invocador apagada, que no sea este sitio web.
- Qué indica su mensaje
- Mantener la comprobación activa con el agente de servicio de IAP como único invocador, generando otra vez el producto con los módulos actuales del golden path.
- Fuente
- control-plane
policy/airframe/cloud_run.rego; no está listada endocs/policy-pack.md
El backend de un producto tiene inicio de sesión único
- Nivel
- Rechazo
- Qué comprueba
- En una raíz de producto, un servicio de backend del balanceador sin IAP.
- Qué indica su mensaje
- Una ruta pública usa la pieza de ingreso externo, que está diseñada.
- Fuente
- control-plane
policy/airframe/cloud_run.rego; no está listada endocs/policy-pack.md
Ninguna dirección pública de base de datos
- Nivel
- Rechazo
- Qué comprueba
- Una instancia de Cloud SQL con una dirección IPv4 pública.
- Qué indica su mensaje
- Ninguna.
- Fuente
- control-plane
policy/airframe/cloud_run.rego
Instancias mínimas por encima de cero
- Nivel
- Advertencia
- Qué comprueba
- Un servicio de Cloud Run que mantiene instancias en ejecución, aparte de la única instancia caliente del sandbox.
- Qué indica su mensaje
- La aprobación de la plataforma, fuera de la criticidad 1; la aprobación está diseñada.
- Fuente
- control-plane
policy/airframe/cloud_run.rego
Una base de datos sidecar es solo de una vista previa
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Un contenedor llamado
databasejunto a un servicio que no es de una vista previa. - Qué indica su mensaje
- Producción y no producción usan Cloud SQL.
- Fuente
- control-plane
policy/airframe/cloud_run.rego; no está listada endocs/policy-pack.md
Un servicio con base de datos sidecar ejecuta una instancia
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Un servicio con un contenedor
databaseque puede escalar a más de una instancia. - Qué indica su mensaje
- Ejecutar una instancia como mucho, porque sus datos viven en la instancia.
- Fuente
- control-plane
policy/airframe/cloud_run.rego; no está listada endocs/policy-pack.md
Una vista previa no crea instancias de base de datos
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Una instancia de Cloud SQL, Redis o AlloyDB etiquetada con el entorno de una vista previa.
- Qué indica su mensaje
- Usar la instancia compartida del sustrato de vistas previas o un sidecar.
- Fuente
- control-plane
policy/airframe/cloud_run.rego; no está listada endocs/policy-pack.md
Recursos de la plataforma y secretos
Sección titulada «Recursos de la plataforma y secretos»Ningún recurso de la plataforma en una raíz de producto
- Nivel
- Rechazo
- Qué comprueba
- En una raíz de producto, cualquiera de los tipos que posee la plataforma, como redes, subredes, cortafuegos, zonas DNS, certificados, proyectos, carpetas, APIs habilitadas, políticas de la organización, políticas de denegación, perímetros, pools de identidades, routers y NAT.
- Qué indica su mensaje
- Ninguna: pertenecen a las raíces de la plataforma.
- Fuente
- control-plane
policy/airframe/platform_owned.rego
Secret Manager es el único almacén, y ningún valor pasa por Terraform
- Nivel
- Rechazo
- Qué comprueba
- Una versión de secreto con su valor en
secret_data, y un secreto en Vault, AWS o Azure. Una versión cuyo valor es de solo escritura,secret_data_wo, pasa, porque queda fuera del plan y del estado. - Qué indica su mensaje
- Un mantenedor agrega el valor en Secret Manager, o el valor es de solo escritura.
- Fuente
- control-plane
policy/airframe/platform_owned.rego
Destrucción
Sección titulada «Destrucción»No se destruye ningún proyecto, base de datos, bucket ni repositorio fuera de una eliminación
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- Un plan que destruye o reemplaza un proyecto, una instancia de Cloud SQL, un bucket o un repositorio de GitLab, salvo que pertenezca a un producto que el catálogo da por eliminado con su fecha pasada. La protección contra borrado que las fábricas de proyectos ponen en los proyectos de un producto activo es el piso debajo de ella.
- Qué indica su mensaje
- Poner el ciclo de vida del producto en eliminado, después de
retire_after, en el catálogo. - Fuente
- control-plane
policy/airframe/lifecycle.rego
El runner de confianza no se reemplaza desde su propio pipeline
- Nivel
- Rechazo
- Qué comprueba
- Un plan que borra o reemplaza la instancia del runner de confianza, lo que terminaría el job que lo aplica.
- Qué indica su mensaje
- Aplicar ese plan desde una laptop con la concesión platform-apply.
- Fuente
- control-plane
policy/airframe/runner.rego; no está listada endocs/policy-pack.md
El archivo de pipeline
Sección titulada «El archivo de pipeline»Estas reglas leen el .gitlab-ci.yml de un repositorio. Los repositorios de la plataforma están exentos de las que tratan del archivo de un producto.
El archivo de un producto conserva las inclusiones de la plataforma
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- El archivo de un producto debe incluir
tf-applyydrift-report, no debe volver a incluir los componentes inyectadosvalidateobuild-test, no debe nombrar un job como un job de la plataforma, comoplan:ogate:, y no debe declarar las etapas de políticas. - Qué indica su mensaje
- Conservar las inclusiones que generó el template, quitar una inclusión inyectada o una etapa de políticas, y dar otro nombre al job propio.
- Fuente
- control-plane
policy/airframe/pipeline.rego
Los componentes se fijan a un commit
- Nivel
- Advertencia en esta versión, rechazo en la siguiente
- Qué comprueba
- En cada repositorio, un componente de control-plane incluido en una rama, una etiqueta o un commit abreviado.
- Qué indica su mensaje
- Fijarlo a un commit completo de control-plane, como hace
airframe pin <sha>. - Fuente
- control-plane
policy/airframe/pipeline.rego
Un job propio de un producto nunca despliega
- Nivel
- Rechazo
- Qué comprueba
- Un job de un producto que declara un
environment, directamente o medianteextends; una inclusión que no es un componente; y un job que dispara otro pipeline. - Qué indica su mensaje
- Quitar el entorno y desplegar con el componente
tf-apply. - Fuente
- control-plane
policy/airframe/pipeline.rego,docs/adr/0026-a-product-job-never-deploys.md
Solo los componentes de la plataforma
- Nivel
- Rechazo
- Qué comprueba
- La inclusión, en un producto, de un componente que no es uno de los ocho propios de control-plane:
tf-apply,drift-report,image-build,promote-artifact,catalog-publish,reconcile,validateybuild-test. - Qué indica su mensaje
- El mensaje enumera los ocho componentes que un producto puede incluir.
- Fuente
- control-plane
policy/airframe/pipeline.rego
Dockerfiles
Sección titulada «Dockerfiles»Las imágenes parten de una imagen base de la plataforma
- Nivel
- Rechazo
- Qué comprueba
- En cada Dockerfile que lista
.airframe/images.yaml, cadaFROMy cadaCOPY --fromoADD --fromque no sea una etapa del mismo archivo debe nombrar una imagen base de la plataforma, fijada por una etiqueta distinta delatesto por un digest, y nunca calculada a partir de un argumento de compilación. - Qué indica su mensaje
- Construir a partir de la imagen base de la plataforma para la pila, nombrada por su etiqueta o su digest.
- Fuente
- control-plane
policy/airframe/dockerfile.rego,docs/adr/0014-approved-base-images-built-in-project-and-checked-on-every-from.md
Estas reglas se ejecutan en el ejecutor, sobre los planes con precio de un merge request aprobado, y deciden el estado de la comprobación Airframe cost. Un plan sin precio, por ejemplo sin una clave de Infracost, no se juzga.
Un aumento de costo grande
- Nivel
- Advertencia
- Qué comprueba
- Un cambio que agrega más de 10 dólares estadounidenses al mes, o más del 25 por ciento.
- Qué indica su mensaje
- La aprobación de la plataforma, que está diseñada.
- Fuente
- control-plane
policy/airframe/cost.rego; no está listada endocs/policy-pack.md
El presupuesto se respeta
- Nivel
- Rechazo
- Qué comprueba
- Un cambio cuyo costo mensual proyectado para el producto supera su
monthly_budgeten el catálogo. - Qué indica su mensaje
- Subir el presupuesto con un merge request del catálogo que aprueben los líderes del dominio, antes de que este cambio pueda fusionarse.
- Fuente
- control-plane
policy/airframe/cost.rego; no está listada endocs/policy-pack.md
Límites conocidos
Sección titulada «Límites conocidos»Estos límites están abiertos en esta versión de la plataforma, y la página de afirmaciones y mecanismos los enumera con el resto:
- Un recurso suelto advierte, nunca se rechaza. Un producto puede declarar recursos fuera de los módulos del golden path; las reglas de rechazo igual se les aplican, y también las reglas sobre los tipos que posee la plataforma.
- Un recurso sin atributo de etiquetas pasa la regla de etiquetas, que comprueba solo las etiquetas que declara un recurso.
- Los Dockerfiles se reconocen por el nombre del archivo. La validación del merge request juzga un cambio solo en un Dockerfile listado cuando el archivo se llama
Dockerfile,Dockerfile.*,*.Dockerfileo*.dockerfile. Un archivo listado con otro nombre, comoContainerfile, se juzga solo cuando el merge request también cambia otro archivo que la validación vigila. - Una advertencia no detiene nada, y nada pone la etiqueta
warnni abre una excepción: la aprobación y el registro de excepciones están diseñados.
Dónde está
En el repositorio control-plane:
