Concesiones y vía de emergencia
En Airframe nadie tiene un derecho permanente a cambiar producción. Cuando una persona de verdad lo necesita, por un incidente o por una de las pocas raíces que todavía se aplican a mano, pide una concesión que dura una o dos horas, otra persona la aprueba, y la solicitud, la aprobación y el motivo quedan escritos. Esta página es la guía práctica: qué concesión pedir, los comandos, qué registrar, y la vía de emergencia aparte para cuando la compuerta de aprobación no puede aprobar un merge.
Identidades y acceso explica por qué funciona así. Una concesión aquí es una concesión de Privileged Access Manager: Google Cloud agrega los roles a su propia cuenta por un tiempo fijo y después los quita.
Lo que nunca necesita una concesión
Sección titulada «Lo que nunca necesita una concesión»La mayor parte del trabajo no la necesita. Tu cuenta de uso diario puede leer los proyectos y sus registros, y el equipo de un producto puede agregar una versión nueva de uno de sus secretos. Todo cambio de infraestructura pasa por un merge request y un pipeline. Volver a ejecutar el pipeline de un producto en main, corregir la deriva en el código y revertir con un merge request de reversión tampoco necesitan una concesión. Pide una concesión solo cuando un merge request no pueda hacer el trabajo.
Qué concesión corresponde
Sección titulada «Qué concesión corresponde»Airframe define cuatro concesiones, como cuatro derechos en roots/pam de landing-zone:
| Necesitas | Concesión, quién aprueba, duración |
|---|---|
| Leer los registros, las métricas o el estado de un proyecto de no producción para investigar | Nivel 1: sin aprobación, 1 hora |
| Corregir algo a mano en los proyectos de la organización de demostración durante un incidente | Nivel 2: una segunda persona, 2 horas |
| Aplicar una raíz que se sigue aplicando desde una laptop, o reemplazar el runner de confianza | Apply de plataforma: una segunda persona, 2 horas |
| Cambiar algo en el nivel de la organización | Organización: una segunda persona, 2 horas |
Hoy el nivel 1 existe solo en el proyecto de ejecución de no producción de la plataforma. La guía de identidad dice que el proyecto de no producción de cada producto con facturación recibe uno de su fábrica de proyectos; ninguna fábrica lo crea todavía, así que esa parte está diseñada. Un apply desde una laptop de la raíz de identidad necesita a la vez la concesión de apply de plataforma y la de organización, porque también cambia vínculos en la organización.
Los miembros del grupo de emergencia, lk-breakglass@, pueden pedir las tres primeras. La concesión de organización la pide un miembro del grupo de plataforma, lk-platform@, y todas las aprobaciones vienen de ese grupo. Privileged Access Manager no deja que quien pide apruebe su propia solicitud (aplicado).
1. Pide la concesión
Sección titulada «1. Pide la concesión»Quién: tú, con la sesión de gcloud abierta con tu propia cuenta de uso diario, nunca con la cuenta de administración.
Indica el derecho, dónde está, cuánto tiempo lo necesitas y por qué. Para una concesión de nivel 2 en la carpeta de la organización de demostración:
gcloud pam grants create \ --entitlement=airframe-level2-admin \ --folder=<folder-id> \ --location=global \ --requested-duration=7200s \ --justification="<qué va a cambiar y por qué>"Las otras tres cambian solo en el derecho y su lugar: airframe-platform-apply en la misma carpeta; airframe-organisation-admin con --organization=<organization-id>; airframe-level1-read con --project=<project-id> y como máximo 3600s. La página de Privileged Access Manager de la consola de Google Cloud hace lo mismo. Una concesión de nivel 1 se activa en el acto; las otras esperan una aprobación. Mientras siga abierta una concesión para el mismo acceso, Privileged Access Manager rechaza una segunda, así que reutiliza la que está abierta.
2. Aprueba la concesión
Sección titulada «2. Aprueba la concesión»Quién: otro miembro de lk-platform@, nunca quien la pidió.
Quien aprueba ve lo que espera su aprobación, lee la justificación y aprueba con un motivo propio:
gcloud pam grants search \ --entitlement=airframe-level2-admin \ --folder=<folder-id> --location=global \ --caller-relationship=can-approve
gcloud pam grants approve <grant-id> \ --entitlement=airframe-level2-admin \ --folder=<folder-id> --location=global \ --reason="<por qué se aprueba>"Hoy una sola persona opera la plataforma, y la segunda aprobación es la segunda cuenta del mantenedor: el mecanismo está aplicado, pero la separación entre dos personas todavía no es real.
3. Usa la concesión para una raíz y deja que venza
Sección titulada «3. Usa la concesión para una raíz y deja que venza»La concesión no te entrega una clave aparte: mientras dura, tu propia cuenta tiene los roles del derecho. Ningún documento de los repositorios da la secuencia exacta de comandos para un apply desde una laptop; el esquema de abajo está armado a partir de los propios archivos de las raíces y de las filas de docs/bootstrap-log.md.
Dónde: landing-zone para las raíces de organización, auditoría e identidad (roots/organisation, roots/audit, roots/wif); roots/runner de control-plane para reemplazar el runner de confianza.
-
En un clon limpio, obtén el commit aprobado y usa la versión de Terraform que nombra el
.terraform-versiondel repositorio. -
Haz que el proveedor de Google de Terraform actúe como tu propia cuenta:
gcloud auth application-default login. -
En el directorio de la raíz, inicializa la raíz contra su estado.
backend.tftiene un bloquegcsvacío, así que pasa el bucket de estado de la plataforma, que nombra la variablestate_bucketde la raíz, y el prefijo de la fila “State” del README de la raíz:Ventana de terminal terraform init \-backend-config="bucket=<platform state bucket>" \-backend-config="prefix=<the State row of the README>" -
Planifica a un archivo, léelo, aplica exactamente ese archivo y planifica otra vez; el último plan debería estar vacío:
Ventana de terminal terraform plan -out=<file>terraform apply <file>terraform plan -
Detente. Los roles salen de tu cuenta cuando vence la concesión.
El diagrama y estos pasos siguen una concesión de apply de plataforma o de organización. Una concesión de nivel 1 no tiene aprobación y no cambia nada: mientras dura, lee los registros, las métricas y el estado del proyecto. Una concesión de nivel 2 es para una corrección a mano durante un incidente, a menudo unos pocos comandos de gcloud en lugar de un apply, como muestran las filas de docs/bootstrap-log.md. Una corrección así es deriva por definición: el plan diario la informa, y termina cuando la corrección se escribe en el código o el siguiente apply la revierte. Consulta Deriva.
4. Registra la concesión
Sección titulada «4. Registra la concesión»Dónde: docs/bootstrap-log.md de landing-zone, una fila por merge request, aprobada por el equipo de plataforma.
Hay dos registros que existen sin que nadie los escriba: Privileged Access Manager guarda cada concesión con quien la pidió, la justificación, quien la aprobó y el motivo, y el registro de auditoría guarda cada cambio hecho con ella, y las lecturas de los servicios cuyos registros de acceso a datos activa la raíz de auditoría: Secret Manager, Cloud SQL, Cloud Storage, IAM y Cloud KMS (aplicado). La fila del registro es una convención, escrita y enseñada, pero nada rechaza una concesión sin ella. Nombra los identificadores de las concesiones, quién las pidió y quién las aprobó, la raíz y el commit aplicado, qué cambió y el plan vacío después. Nunca pegues en ella una credencial, un secreto ni un token.
Vía de emergencia cuando la compuerta de aprobación no puede aprobar o no se puede alcanzar
Sección titulada «Vía de emergencia cuando la compuerta de aprobación no puede aprobar o no se puede alcanzar»Todos los repositorios menos uno necesitan la aprobación de la compuerta de aprobación antes del merge, y todo pipeline salvo los de ese repositorio empieza con gate:integrity, que falla de forma cerrada cuando la compuerta no responde. Así que una compuerta caída bloquea toda corrección, incluida una corrección de la propia compuerta. El ADR-0032 de control-plane fija la salida en dos etapas. Se aplica cuando gate:integrity falla con gate unreachable: fail closed en más de un repositorio, o cuando la compuerta deja de aprobar merge requests que su modelo acepta. Una caída de GitLab.com no es una caída de la compuerta, y nada de esto ayuda con ella.
La persona que lo nota abre un issue en control-plane con el enlace del trabajo que falla y lleva en él una cronología.
Etapa 1: recupera la compuerta
Sección titulada «Etapa 1: recupera la compuerta»- Lee el síntoma:
https://gate.projectairframe.dev/healthy las líneas de registro de la compuerta en Grafana. Ninguno necesita una concesión. - Si la causa es la última revisión, pide una concesión de nivel 2 con el issue como justificación, haz que otro miembro del grupo de plataforma la apruebe, y dirige el tráfico de Cloud Run a la última revisión que funcionó. No se crea ninguna revisión nueva, así que Binary Authorization no vuelve a evaluarse. En el ensayo esto tardó unos 22 segundos en cada sentido.
- Si la causa es una credencial, un mantenedor agrega una versión nueva del secreto que lee la compuerta, bajo la misma concesión. El valor nunca va al issue.
Mientras la compuerta está caída, el pipeline no es el camino de vuelta: construir la imagen de la compuerta necesita a la compuerta. La reversión es lo que la hace servir otra vez, y la corrección llega después como un merge request normal.
Etapa 2: un repositorio fuera de las dos políticas, por dos horas
Sección titulada «Etapa 2: un repositorio fuera de las dos políticas, por dos horas»Solo cuando la etapa 1 no restableció la compuerta en 30 minutos y un cambio en un repositorio no puede esperar.
- Dónde: security-policies,
.gitlab/security-policies/policy.yml. Un merge request, sin nada más, hace dos cambios para ese repositorio: sale del alcance de la política de aprobaciónrequired ownership gate, y entra en las exclusiones de la política de ejecución de pipelines de todo el grupo, junto a security-policies. security-policies está fuera de esa política para que este merge request no espere a la compuerta para la que existe. - Quién aprueba: una persona del catálogo, con nombre, que no sea su autora ni haya hecho commits en él. Hoy las personas con nombre que aprueban son todas cuentas del propio mantenedor: el mecanismo está aplicado, pero la separación entre dos personas todavía no es real.
- El merge request inverso se abre al mismo tiempo y queda esperando su aprobación, de modo que terminar la ventana es una aprobación y un merge.
En el repositorio, durante la ventana, el merge request urgente hace el merge con la aprobación de una persona con nombre y su propia validación. El ejecutor no planifica nada para él, así que quien revisa lee el cambio y la salida de la validación, y su pipeline de main aplica solo raíces que no toman una imagen. Sus pipelines no llevan gate:integrity, así que lo que todavía se interpone entre ellos y las nubes son los vínculos de federación de identidades de carga de trabajo con la referencia protegida y el entorno. Todos los demás repositorios conservan los dos controles. El repositorio de un producto no puede usar el procedimiento, porque su merge también espera la verificación de estado “Airframe cost”, que solo fija la compuerta.
Terminar la ventana
Sección titulada «Terminar la ventana»- La compuerta sirve otra vez:
/healthresponde 200. Si la etapa 1 fijó el tráfico en una revisión anterior, devuelve el tráfico a la última. - Haz el merge del merge request inverso. El archivo de políticas queda idéntico a como estaba antes de la ventana.
- Deja que la concesión venza. Quien pidió una concesión no puede revocarla, porque revocar necesita un rol que nadie tiene de forma permanente.
- Cierra el issue con su cronología y los identificadores de los eventos de auditoría de GitLab de la caída, leídos en las páginas de eventos de auditoría del grupo y de cada proyecto que cambió. El receptor de auditoría, un segundo destino de transmisión, los guarda en el bucket de auditoría bloqueado mientras la compuerta está caída; si también estaba caído, GitLab no vuelve a enviarlos, y los tipos que solo transmite no se guardan en ningún lugar: dilo en el issue. Después escribe un análisis posterior en cinco días hábiles.
El límite de dos horas se verifica y no se aplica por la fuerza. En el pipeline programado de control-plane, que se ejecuta una vez al día, breakglass:check compara el archivo de políticas de security-policies con el estado normal, avisa mientras una diferencia tiene menos de dos horas y falla después, nombrando los repositorios. breakglass:report mantiene abierto un issue hasta que las políticas coinciden otra vez. Solo el merge request inverso termina una ventana.
Qué se ensayó
Sección titulada «Qué se ensayó»El 2026-10-02 el procedimiento se ejecutó en un repositorio de la plataforma, en dos partes, y quedó registrado en docs/rehearsals/2026-10-02-the-gate-unreachable.md de landing-zone. Con la compuerta en funcionamiento, la regla de aprobación salió del repositorio 10 segundos después del primer merge y volvió 16 segundos después del inverso. Luego la compuerta quedó inalcanzable durante dos minutos: un pipeline de otro repositorio falló de forma cerrada 10 segundos después de empezar, el pipeline de security-policies no se vio afectado, y quien pidió la concesión no pudo revocarla, así que venció sola. El ensayo también mostró que la compuerta no puede volver a desplegarse sola por su propio pipeline mientras está caída. control-plane guarda una copia espejo del archivo de políticas, y su trabajo policy:schema falla mientras las dos difieren, hasta que el merge inverso las vuelve a igualar.
Dónde está
En el repositorio landing-zone:
- roots/pam/: los cuatro derechos
- docs/adr/0008: concesiones para las raíces que se aplican desde una laptop
- docs/guides/identity.md: quién puede hacer qué
- docs/bootstrap-log.md: el registro de cada intervención a mano
- docs/rehearsals/2026-10-02-the-gate-unreachable.md: el ensayo de la vía de emergencia
En el repositorio security-policies:
En el repositorio control-plane:
