Skip to content

The gate and the executor

A merge request’s pipeline runs code that nobody has reviewed yet, so on Airframe it is never trusted with cloud credentials. Two parts of the platform do the trusted work instead. The gate decides whether a merge request has been approved by the right people, and the executor is the one place where a merge request’s plans, image builds and previews run with real identities. This page explains what each one does, and in what order.

Why a merge request’s pipeline is untrusted

Section titled “Why a merge request’s pipeline is untrusted”

Anyone who can push a branch can change the pipeline file on that branch. If that pipeline could obtain a product’s identity, a single push nobody had reviewed could read or change the product’s cloud projects.

So a merge request’s own pipeline gets no identity at all. It runs on the platform’s untrusted runner, a machine of its own that holds no credential a job could use and cannot reach the cloud’s metadata server or the platform’s networks, and it does only what needs no credential: formatting, Terraform’s validation without a backend, the policy pack on the code, the catalog’s checks, the application’s build and tests. Most of these are what airframe validate runs on a laptop, too.

Everything that needs to see the real cloud waits until a person who owns the code has approved the change.

a merge requestits ownersapprovethe gate checksand approvesthe executor:plans, cost, buildthe mergemain pipeline:plan, policy, apply

The gate is a small service in the platform’s continuous integration project. It answers three kinds of question.

Has this merge request been approved by its current owners? When someone approves a merge request, GitLab calls the gate. The gate reads the ownership model from the catalog’s protected main branch, never from the change itself, and checks the approvals at the merge request’s latest commit. The author’s approval and the committers’ approvals never count. If the right people have approved, the gate adds its own approval, bound to that exact commit, and starts the executor. A merge request cannot merge without the gate’s approval: a GitLab approval policy in the security-policies repository requires it in each repository it names, which today is every repository but security-policies itself.

A new repository, such as a product created after that list was last changed, is not covered until two merge requests add it: one to the gate’s list of enforced repositories in control-plane, then one to the policy’s scope in security-policies. Until then it needs only the approval of a named person who did not write the change.

May this pipeline run? Every pipeline in the group but security-policies’ own starts with a job, gate:integrity, that the repository cannot remove. It sends the job’s signed token to the gate, at an address written in the job itself: no variable of a project or a group can change it, and an empty address fails the job like an unreachable gate. On a protected main branch, the gate lets the pipeline continue only for the latest commit of a merged merge request, or for a product repository’s first commit generated from the catalog. It also fails a pipeline that uses a revoked release.

What did this change cost? For a product’s merge request, the gate adds up the monthly cost of the executor’s priced plans and sets a status check called “Airframe cost”. It fails when the total, or any single root, is above the product’s budget in the catalog, and GitLab keeps the merge closed until it passes.

The executor is a pipeline of the control-plane repository that runs on the platform’s trusted runner, a machine inside the platform’s own network. Only the gate can start it, with a trigger token only the gate holds.

When a run starts, the executor checks everything again before it holds any credential: that the merge request’s latest commit is still the approved one, that its approvals are still satisfied, and that the gate still authorizes that commit. Then, for a product, it:

  • plans every Terraform root of the product with the product’s plan identity, which can read and change nothing, and posts the plans on the merge request;
  • prices the plans with Infracost, a tool that estimates the monthly price of a Terraform plan, and reports the cost to the gate;
  • has the trusted builder build the commit’s container images;
  • deploys the merge request’s preview with the non-production apply identity.

The executor can use every product’s plan identity and non-production apply identity, and no production one. Nothing it does before a merge can change production.

Once the merge request is merged, the pipeline on the repository’s protected main branch takes over, on the trusted runner, under each root’s own identity:

  1. build:request asks the gate for the images the executor built at the approval.
  2. plan:<root>, one job per root, plans it against the real infrastructure.
  3. policy:<root> runs the policy pack on that plan, and the apply needs it to pass.
  4. apply:<root> applies the plan. Non-production applies on its own; for production, the sandbox goes first, then production with the promoted image.

If someone merges before the executor’s run has finished, the run’s check of the commit fails, because the gate no longer authorizes that commit for a merge request run. Nothing is skipped: build:request on main finds no finished build, asks the gate for one, and waits for it. This happened on 2026-09-30 with a change to this website, and the deploy simply took a few minutes longer.

An attacker who can only push a branch gets a pipeline with no credentials. One who can approve their own change gets nowhere, because the gate does not count the author. A change that passed review and then gained a new commit loses the gate’s approval, because that approval is bound to the commit it checked. And because production is applied only from the protected main branch, under an identity no merge request can obtain, the only road to production is a reviewed, merged change.

Where it lives

In the control-plane repository:

MIT license. Copyright Airframe contributors.

This site describes platform release 2026.10.20-1.