O controle de aprovação e o executor
O pipeline de um merge request roda código que ninguém revisou ainda, então no Airframe ele nunca recebe credenciais da nuvem. Duas partes da plataforma fazem o trabalho confiável no lugar dele. O controle de aprovação decide se um merge request foi aprovado pelas pessoas certas, e o executor é o único lugar onde os planos, as compilações de imagens e as prévias de um merge request rodam com identidades reais. Esta página explica o que cada um faz, e em que ordem.
Por que o pipeline de um merge request não é confiável
Seção intitulada “Por que o pipeline de um merge request não é confiável”Qualquer pessoa que possa enviar uma branch pode mudar o arquivo de pipeline nessa branch. Se esse pipeline pudesse obter a identidade de um produto, um único push sem revisão poderia ler ou mudar os projetos na nuvem do produto.
Por isso, o pipeline do próprio merge request não recebe nenhuma identidade. Ele roda no runner não confiável da plataforma, uma máquina própria que não tem nenhuma credencial que um job possa usar e não alcança o servidor de metadados da nuvem nem as redes da plataforma, e faz só o que não precisa de credenciais: a formatação, a validação do Terraform sem backend, o pacote de políticas sobre o código, as verificações do catálogo, a compilação e os testes da aplicação. A maior parte disso também é o que airframe validate roda em um notebook.
Tudo o que precisa ver a nuvem real espera até que uma pessoa responsável pelo código tenha aprovado a mudança.
O controle de aprovação
Seção intitulada “O controle de aprovação”O controle de aprovação é um pequeno serviço no projeto de integração contínua da plataforma. Ele responde três tipos de pergunta.
Este merge request foi aprovado pelos seus responsáveis atuais? Quando alguém aprova um merge request, o GitLab chama o controle de aprovação. Ele lê o modelo de responsáveis a partir da branch main protegida do catálogo, nunca da própria mudança, e verifica as aprovações no último commit do merge request. A aprovação do autor e as de quem fez commits nunca contam. Se as pessoas certas aprovaram, o controle adiciona sua própria aprovação, vinculada àquele commit exato, e inicia o executor. Um merge request não pode ser integrado sem a aprovação do controle: uma política de aprovação do GitLab no repositório security-policies a exige em cada repositório que ela nomeia, que hoje são todos os repositórios menos o próprio security-policies.
Um repositório novo, como o de um produto criado depois da última mudança dessa lista, não fica coberto até que dois merge requests o adicionem: um à lista de repositórios exigidos do controle no control-plane, e depois um ao alcance da política no security-policies. Enquanto isso, ele só precisa da aprovação de uma pessoa nomeada que não escreveu a mudança.
Este pipeline pode rodar? Todo pipeline do grupo, menos os do security-policies, começa com um job, gate:integrity, que o repositório não pode remover. Ele envia ao controle de aprovação o token assinado do job, para um endereço escrito no próprio job: nenhuma variável de um projeto ou de um grupo pode mudá-lo, e um endereço vazio faz o job falhar como um controle inalcançável. Em uma branch main protegida, o controle só deixa o pipeline continuar para o último commit de um merge request integrado, ou para o primeiro commit do repositório de um produto gerado a partir do catálogo. Ele também faz falhar um pipeline que usa uma versão da plataforma revogada.
Quanto custa esta mudança? Para o merge request de um produto, o controle soma o custo mensal dos planos com preço do executor e define uma verificação de status chamada “Airframe cost”. Ela falha quando o total, ou qualquer raiz sozinha, passa do orçamento do produto no catálogo, e o GitLab mantém o merge fechado até ela passar.
O executor
Seção intitulada “O executor”O executor é um pipeline do repositório control-plane que roda no runner confiável da plataforma, uma máquina dentro da rede da própria plataforma. Só o controle de aprovação pode iniciá-lo, com um token de disparo que só ele tem.
Quando uma execução começa, o executor verifica tudo de novo antes de ter qualquer credencial: que o último commit do merge request ainda é o aprovado, que suas aprovações ainda estão satisfeitas, e que o controle ainda autoriza esse commit. Depois, para um produto, ele:
- planeja cada raiz do Terraform do produto com a identidade de plan do produto, que pode ler e não muda nada, e publica os planos no merge request;
- coloca preço nos planos com o Infracost, uma ferramenta que estima o preço mensal de um plano do Terraform, e informa o custo ao controle de aprovação;
- faz o construtor confiável construir as imagens de contêiner do commit;
- implanta a prévia do merge request com a identidade de apply de não produção.
O executor pode usar a identidade de plan e a identidade de apply de não produção de cada produto, e nenhuma de produção. Nada do que ele faz antes de um merge pode mudar a produção.
Depois do merge
Seção intitulada “Depois do merge”Depois que o merge request é integrado, o pipeline da branch main protegida do repositório assume, no runner confiável, com a identidade própria de cada raiz:
build:requestpede ao controle de aprovação as imagens que o executor construiu na aprovação.plan:<root>, um job por raiz, a planeja contra a infraestrutura real.policy:<root>roda o pacote de políticas sobre esse plano, e o apply precisa que ele passe.apply:<root>aplica o plano. A não produção é aplicada por conta própria; para a produção, o sandbox vem primeiro, depois a produção com a imagem promovida.
Se alguém integra o merge request antes de a execução do executor terminar, a verificação do commit nessa execução falha, porque o controle de aprovação não autoriza mais aquele commit para uma execução de merge request. Nada é pulado: build:request na main não encontra uma compilação terminada, pede uma ao controle e espera por ela. Isso aconteceu em 2026-09-30 com uma mudança neste site, e a implantação simplesmente levou alguns minutos a mais.
O que isso protege
Seção intitulada “O que isso protege”Um atacante que só pode enviar uma branch recebe um pipeline sem credenciais. Um que pode aprovar a própria mudança não chega a lugar nenhum, porque o controle não conta o autor. Uma mudança que passou pela revisão e depois recebeu um commit novo perde a aprovação do controle, porque essa aprovação é vinculada ao commit que ele verificou. E como a produção só é aplicada a partir da branch main protegida, com uma identidade que nenhum merge request pode obter, o único caminho até a produção é uma mudança revisada e integrada.
Onde fica
No repositório control-plane:
