Pipeline components
Every Airframe repository builds its pipeline from the platform’s components, shared building blocks kept in the control-plane repository, rather than from jobs of its own. This page lists each component a repository may include, the jobs it adds and what it needs to run, then the jobs the platform injects into pipelines whatever their files say, so you can read any repository’s pipeline and know where each job comes from.
How to read the tables
Section titled “How to read the tables”A component is included as gitlab.com/projectairframe/control-plane/<name>@<commit>, at a full commit, which the command airframe pin writes; the policy pack warns on a branch, a tag or a short commit. It takes inputs, never variables. A product’s pipeline file is rendered by the golden path’s template, and the policy pack denies a product file that includes anything but eight of these components or declares a job that deploys (enforced). The policy rules page lists those rules.
Jobs run on one of two runners: the untrusted runner, which holds no credential and runs anything a merge request brings, and the trusted runner, which runs only on a protected main and obtains identities through workload identity federation. The glossary explains both.
The tables describe release 2026.10.01-1, whose control-plane commit is c53c0bc. A row marked designed is a component the contracts name that is not built.
The components
Section titled “The components”tf-apply
- Jobs
plan:<name>, orplan-after:<name>for a root that plans after other roots' applies;policy:<name>;apply:<name>;run-job:<name>when the root runs a job after its apply; anddrift:<name>on the scheduled pipeline.- Inputs a repository sets
- One include per Terraform root:
name,root,root_kind,identity,state_bucket,state_prefixandenvironment. A product's file also setslifecycle,extra_changes,run_job,run_job_afterand, for production,after. Platform roots may setreads_catalog,plan_after,plan_late,secret_env,smoke,drift_onlyandforget_projects. - What it needs
- The trusted runner, a protected main, and the root's identity in the root's environment. The plan, policy and apply jobs run on main only, when the root's files changed.
- Source
- control-plane
templates/tf-apply/template.yml,docs/pipeline.md; golden-pathtemplate/.gitlab-ci.yml.jinja
drift-report
- Jobs
drift:report, on the scheduled pipeline, after the drift jobs.- Inputs a repository sets
- None in practice: every input has a default.
- What it needs
- The trusted runner; the audit identity, in the environment
platform/audit; the audit account's GitLab token, read from Secret Manager in the job; and a schedule on main that a maintainer creates. - Source
- control-plane
templates/drift-report/template.yml,docs/pipeline.md
image-build
- Jobs
build:request, on main.- Inputs a repository sets
wait_minutesandgate_url. Theidentity,environmentand registry inputs are retired and ignored.- What it needs
- The untrusted runner and the job's token for the gate, with no cloud identity. The trusted builder built the commit at the approval, or builds it now at the job's request.
- Source
- control-plane
templates/image-build/template.yml
promote-artifact
- Jobs
deploy:promote, on main, afterbuild:request.- Inputs a repository sets
wait_minutesandgate_url. Its former inputs are accepted and ignored.- What it needs
- No credential: it asks the gate, and the executor copies the image by digest into the production registry as the artifact promoter. The production apply waits for it.
- Source
- control-plane
templates/promote-artifact/template.yml,docs/pipeline.md
catalog-publish
- Jobs
validate:fragmenton merge requests;release:catalogon main.- Inputs a repository sets
kind,path,identityandenvironment; a platform repository also setsname.- What it needs
validate:fragment: the untrusted runner, no credential.release:catalog: the trusted runner and the repository's own identity, for a product its production apply identity in the environmentprod.- Source
- control-plane
templates/catalog-publish/template.yml,docs/pipeline.md
reconcile
- Jobs
<name>:reconcile, by conventionedge:reconcileandgrafana:reconcile, on main after the applies.- Inputs a repository sets
name,repository(landing-zoneoroperations),afterandchanges.- What it needs
- The job's token for the gate, which starts the platform repository's main pipeline with the platform's own trigger token. No cloud identity.
- Source
- control-plane
templates/reconcile/template.yml
progress
- Jobs
progress:track, in the catalog's main pipeline after a merge that changed a product file.- Inputs a repository sets
- None in practice; only the catalog includes it.
- What it needs
- The untrusted runner and the job's token for the gate, which writes the note on the merged merge request. It follows the merge for up to three hours.
- Source
- control-plane
templates/progress/template.yml; catalog.gitlab-ci.yml
validate
- Jobs
validate:terraform,validate:tofu,validate:tflint,validate:policyandvalidate:catalog.- Inputs a repository sets
- A platform repository sets
terraform_roots,root_kindand, in the catalog,catalog_lint. A product sets nothing: the product policy injects it. - What it needs
- The untrusted runner, no credential and public images only.
- Source
- control-plane
templates/validate/template.yml,docs/pipeline.md
build-test
- Jobs
build:test-node,build:test-pythonwithbuild:web-python, orbuild:test-java, chosen by the stack's files; thenbuild:quality.- Inputs a repository sets
- None: it is injected into every product pipeline and never included.
- What it needs
- The untrusted runner and no credential. The coverage and findings thresholds come from the product's
qualityin the catalog. - Source
- control-plane
templates/build-test/template.yml,docs/pipeline.md
A product’s rendered file includes image-build, promote-artifact, four tf-apply includes for prod, sandbox, np and grafana, drift-report, catalog-publish, and reconcile twice. A platform repository with Terraform roots includes validate and one tf-apply per root it applies; most also include drift-report and catalog-publish, and those that build images image-build and promote-artifact.
The injected jobs
Section titled “The injected jobs”GitLab policies kept in the security-policies repository add these jobs to pipelines. A repository’s own file cannot remove or replace an injected job (enforced by GitLab’s pipeline execution policies), so a team sets nothing here.
gate:integrity
- Where it runs
- Every pipeline of every repository in the group but security-policies, in the stage before all others.
- What it does
- Asks the gate for its verdict on the pipeline's commit and fails when the verdict is fail, when the address is empty or when the gate cannot be reached. The address is the job's own, and the policy refuses variable overrides, so no project, group or pipeline variable reaches the job. The gate also fails a pipeline pinned to a revoked release.
- What it needs
- One token whose audience is the gate. It checks out no code.
- Source
- security-policies
templates/airframe.yml,.gitlab/security-policies/policy.yml
validate:injected
- Where it runs
- Every pipeline in the group but security-policies', on merge requests and on main.
- What it does
- Marks the validation stage as present; the components run the checks.
- What it needs
- Nothing.
- Source
- security-policies
templates/airframe.yml
The product checks
- Where it runs
- Every pipeline of a repository in the journey groups, where the products are.
- What it does
- The
validatecomponent on the rootsinfra/prod,infra/np,infra/sandbox,infra/grafanaandinfra/eph, with the policy pack, and thebuild-testcomponent. - What it needs
- The untrusted runner and no credential.
- Source
- security-policies
templates/product.yml,.gitlab/security-policies/policy.yml
Secret detection, dependency scanning and SAST
- Where it runs
- Every merge request pipeline in the group, and a daily scan of every default branch.
- What it does
- GitLab's own scanners. Their findings appear on the merge request and block nothing yet.
- What it needs
- Nothing from the repository: the scan execution policy defines the jobs.
- Source
- security-policies
.gitlab/security-policies/policy.yml
Named in the contracts, not components today
Section titled “Named in the contracts, not components today”deploy-cloud-rundesigned
- Jobs
deploy:sandbox,deploy:prod,deploy:canary,deploy:shift-<pct>anddeploy:rollback- Today
- Not built. The
tf-applyapplies deploy each image by digest, and criticality 1's canary order is designed. - Source
- landing-zone
docs/contracts.md5.1,docs/adaptations.md
security-scandesigned
- Jobs
verify:dependencies,verify:containerandverify:licences- Today
- Not built as a component. GitLab's scanners arrive through the scan execution policy, and the trusted builder scans each image it builds.
- Source
- landing-zone
docs/contracts.md5.1; control-planedocs/pipeline.md
pact-publish, pact-can-i-deploydesigned
- Jobs
verify:pact-publishanddeploy:can-i-deploy- Today
- Not built: no contract broker runs.
- Source
- landing-zone
docs/contracts.md5.1
releasedesigned
- Jobs
release:tag- Today
- Not built.
- Source
- landing-zone
docs/contracts.md5.1
opsdesigned
- Jobs
ops:restart,ops:scale,ops:rollbackand six more operational jobs- Today
- Not built.
- Source
- landing-zone
docs/contracts.md5.1
renovatedesigned
- Jobs
ops:renovate, on a schedule- Today
- Not built.
- Source
- landing-zone
docs/contracts.md5.1
tf-plan, cost-estimate, preview-env, destroy-on-close
- Jobs
- The plans at approval, their price, a preview and its destroy
- Today
- Built as the executor's runs, which the gate starts. A repository includes none of them.
- Source
- landing-zone
docs/contracts.md5.1, 5.3; control-planeexecutor/
The contracts give some jobs older names, such as deploy:apply-<root>. The tables use the names the components define.
Where it lives
In the control-plane repository:
In the security-policies repository:
