A change's path
Every change to a product on Airframe, a new feature, a database, a configuration tweak, takes the same path to production, whether a person or a coding agent wrote it. This page walks that path in nine steps and names the check at each one, so you can see what stops a bad change and where. The example is a change to the demo organization’s orders product.
1. A person or a coding agent makes a change
Section titled “1. A person or a coding agent makes a change”A developer, or a coding agent working for one, changes the product’s repository on a branch: the application in apps/, the infrastructure in infra/, or the pipeline file. The skills from platform-skills teach a coding agent where each kind of change belongs and what the rules expect.
2. Local validation
Section titled “2. Local validation”Before opening a merge request, the author runs airframe validate on the laptop. It needs no credentials and runs most of the merge request’s validation: Terraform’s formatting and validation, OpenTofu and tflint where they are installed, and the policy pack on the roots, the pipeline file and the declared Dockerfiles. A failing rule names the resource and, often, what to do instead, so the author fixes it and validates again.
3. The merge request’s pipeline
Section titled “3. The merge request’s pipeline”The merge request’s pipeline runs on the platform’s untrusted runner, a machine that holds no cloud credential a job could use. The repository cannot remove the jobs injected into it:
gate:integrityasks the gate whether this pipeline may run, and fails one that uses a revoked release;- the validation, including the policy pack, on the product’s roots and pipeline file;
- the application’s build and tests, with the test coverage the catalog entry requires;
- GitLab’s secret detection, dependency scanning and static analysis.
A denial or a failed test fails the pipeline, and GitLab will not merge until it passes.
4. The owners approve, then the gate
Section titled “4. The owners approve, then the gate”Someone who did not write the change approves it: a named person from the catalog, never a role. Which people count depends on what the change touches, according to the catalog’s ownership model: the team for infra/, the team or the platform team for the pipeline file.
When they have approved, GitLab calls the gate. The gate checks the approvals at the latest commit, adds its own, bound to that commit, and starts the executor. A new commit pushed after this resets the approvals and the cycle starts again.
5. The executor’s plans and the cost check
Section titled “5. The executor’s plans and the cost check”The executor runs on the trusted runner and checks again that the commit is the approved one. Then, with the product’s own identities:
- it plans every Terraform root of the product with the plan identity, which can change nothing, and posts the plans on the merge request for the reviewers;
- it prices the plans with Infracost, and the gate sets the “Airframe cost” status check, which fails when the total or any single root is above the product’s monthly budget;
- it has the trusted builder build the commit’s container images;
- it deploys a preview of the change with the non-production identity, at its own hostname, destroyed when the merge request is merged or closed, or when its time runs out.
6. The merge
Section titled “6. The merge”GitLab merges only when the pipeline has passed, the right people and the gate have approved the latest commit, and the cost check has passed. (The gate’s approval is required in every repository the approval policy names, which today is every repository but security-policies; a product repository created since joins that list by two merge requests, as the gate’s page explains.) Merges are fast-forward only, so what was approved and tested is exactly what lands on main.
7. The main pipeline applies
Section titled “7. The main pipeline applies”On the protected main branch, the pipeline runs on the trusted runner, each root under its own apply identity, which only a job of this repository on a protected branch in the right environment can obtain. gate:integrity first confirms that this commit is the head of a merged merge request. Then, for each root, plan:<root> plans it again against the real infrastructure, policy:<root> runs the policy pack on the plan, and apply:<root> applies it only if that passed. A plan the executor’s cost rules refused stops here too.
8. Images built, attested and promoted
Section titled “8. Images built, attested and promoted”The images were built at the approval, by the trusted builder, from the approved commit. Before a separate identity signs the build attestation, the executor checks Cloud Build’s own record of the build. On main, deploy:promote has the images copied by digest into the production registry, which adds a second attestation. Production waits for that step.
9. Production
Section titled “9. Production”The product’s services run on Cloud Run. Every service deployed through the golden path’s Cloud Run module opts into its project’s Binary Authorization policy, which in a billed product’s production project admits only an image carrying both attestations. Nothing yet requires a service to opt in: one deployed without that module runs without the check, a gap the zero standing privilege page also states.
The change is live. If anything along the way failed, the step that failed says why, and the fix is another merge request down the same path.
Where it lives
In the control-plane repository:
