Skip to content

security-policies

The security-policies repository holds the rules GitLab enforces across the whole projectairframe group: the jobs it injects into pipelines whether a repository asks for them or not, and the rules for who must approve a merge. It is small, a handful of files, and it is the one repository the gate does not judge. That is deliberate: it is the platform’s break-glass.

A product’s pipeline file belongs to its team, so anything the platform must always run cannot live there. GitLab’s security policies run beside a repository’s own pipeline and cannot be removed by it. This repository is where those policies live, so changing them is a reviewed merge request like everything else.

One policy file, .gitlab/security-policies/policy.yml, holds four kinds of policy:

  • Two pipeline execution policies. The group-wide one injects two jobs into every pipeline: gate:integrity, which asks the gate whether the pipeline may run, and validate:injected. The gate’s address is written in the job itself, an empty one fails closed, and the policy excludes this repository’s own pipelines. The product one injects the validate component on the product’s roots and the build-test component, with its test evidence, into every product repository’s pipeline.
  • Two merge request approval policies. The first requires, on every default branch, the approval of a named person from the catalog who is neither the author nor a committer; approvals reset when new commits are pushed. The second, the “required ownership gate”, requires the gate’s own approval at the merge request’s latest commit, in each repository its scope names: today, every repository but this one. A repository created since joins by a merge request here, after the gate’s own list has added it.
  • A scan execution policy: GitLab’s secret detection, dependency scanning and static analysis on every merge request and every day.

Both pipeline execution policies refuse variable overrides: no project, group, instance or pipeline variable reaches the jobs they inject. A setting in a project cannot point gate:integrity at another address, empty it, or change how the validation tools behave.

Two templates hold the injected jobs, and a script, approvers.py, checks that the approvers the policy names are exactly the catalog’s active people with a GitLab account, named one by one, never a role.

  • Every repository runs its jobs. The group-wide jobs reach every pipeline in the group but this repository’s own; the product jobs reach every repository in the journey groups, where products live.
  • The gate depends on it. The required ownership gate is what makes the gate’s approval a condition of merging.
  • control-plane started it. control-plane’s gitlab root wrote these files once, at the bootstrap, and has ignored their content since.
  • It is part of every release. A release names this repository’s commit, together with the other parts.

Who changes it, and why it is the break-glass

Section titled “Who changes it, and why it is the break-glass”

A change here is a merge request approved by a named person who did not write it. The pipeline checks the policy file against GitLab’s published schema and runs the approvers check. But the gate’s approval is not required here, and this repository’s own pipelines carry no gate:integrity, so a merge request here does not wait on the gate.

The reason is recovery. If the gate cannot approve or cannot be reached, every other repository is blocked, including any fix to the gate. A merge request here, under the non-author approval alone, can take one repository out of the required ownership gate’s scope and out of the group-wide pipeline execution policy for at most two hours, and that repository can merge again; the reverse merge request puts both back. This was rehearsed on 2026-10-02: with the gate up, the rule left a repository 10 seconds after the merge and returned 16 seconds after the reverse, and with the gate unreachable for two minutes, this repository’s pipeline still passed. Grants and break-glass has the whole procedure.

So what protects this repository is the approval of a named person, never its author. Today the approvers are the maintainer’s accounts, because one person runs the platform: the mechanism is enforced, but the separation between two people is not yet real.

Where it lives

In the security-policies repository:

MIT license. Copyright Airframe contributors.

This site describes platform release 2026.10.20-1.