Using the platform with GitLab¶
Status: IMPLEMENTED and tested end to end against GitLab CE 19.5 with a real runner (backend/tests/integration/test_gitlab_live.py,
nightly in CI). Evidence from GitLab is capped at C2; ADR-033 explains why.
What the platform does on GitLab¶
| GitLab | |
|---|---|
| Settings evidence | Protected default branch, merge request approvals (Premium), "pipelines must succeed", CODEOWNERS (sections supported), project members, visibility, secret push protection (Ultimate) |
| Scan evidence | The shipped CI/CD components (pipelines/gitlab/): Semgrep, OSV-Scanner, gitleaks, Checkov, Syft |
| Proof that the approved component ran | The job's commit is linted with a read-only token. Every include must be pinned to a commit SHA, and the merged job must equal the component file at an approved SHA (only scheduling keys such as stage may differ) |
| Tickets | GitLab Issues (optional), or Jira |
| Delivery | Group webhook for job and push events (Premium); otherwise the platform polls finished component jobs on its schedule |
Set up (once per organization)¶
You need a GitLab group and a group Owner's personal access token (scope api) for the set-up only. It is not stored.
cd backend
# 1. The platform's read-only token (Reporter; read_api + read_repository), and the webhook on Premium
GITLAB_ADMIN_TOKEN=... uv run aap bootstrap gitlab --url https://gitlab.example.org --group example-org \
--admin-token-env GITLAB_ADMIN_TOKEN --public-url https://aap-hooks.example.org # add --with-issues for GitLab Issues
# 2. Create <group>/security-components and render the components into it; merge through review
uv run aap pipelines export --provider gitlab --to ../../security-components
# 3. Approve the merged commit (edits config/trusted-producers.yaml → gitlab:; merge that through review)
uv run aap pipelines approve --provider gitlab --repository example-org/security-components --sha <commit> --release v1.0.0
# 4. The include each application project adds to its .gitlab-ci.yml
uv run aap pipelines caller --provider gitlab --host gitlab.example.org --repository example-org/security-components \
--sha <commit> --release v1.0.0
Settings for the deployment: AAP_GITLAB_URL, AAP_GITLAB_GROUP (or plugins.gitlab in aap.yaml).
Rules for application projects¶
- Include the components exactly as
aap pipelines callerprints them, pinned to the approved SHA. - Do not override the included jobs (
aap-sast,aap-sca, ...) in your.gitlab-ci.yml. A job that differs from the approved component is rejected (UNAPPROVED_WORKFLOW_REF) and the rejection names the changed keys. You may changestage(an input), andtags,rules,needsandwhen. - Includes from branches, tags or URLs make every job's evidence unverifiable: pin them to commit SHAs.
- Register the application from the platform's Register an application page (Source control: GitLab), or
aap apps register --provider gitlab group/project.
Known limits¶
- C2 at most. Project CI/CD variables reach the job environment and the platform's Reporter token cannot see them; no GitLab signature names the component. The components run the evidence tool with a scrubbed environment, which narrows but does not remove the first limit.
- GitLab Free. Merge request approvals cannot be required, so the review control is not satisfied (that is the
true state). Protected environments and CI/CD variable names are not readable, so
repo.environmentsis a gap. - Container scanning. No GitLab component yet: it needs the image digest as an input, and inputs other than
stagewould break the "equals the approved component" check. Scan images from a GitHub workflow or add the evidence manually until a design for verified inputs lands. - Semgrep rules come from the Semgrep registry at run time (
p/default). Vendor them intosecurity-componentsto pin them.
Try it locally¶
deploy/local/gitlab.sh starts GitLab CE and a runner, creates the group, runs aap bootstrap gitlab, registers a
runner and prints the command for the live end-to-end test (~4 GB RAM, first start several minutes).