Centralized CI Pipeline Templates¶
Einordnung ins Overtime-Projekt
Mit wachsender Anzahl an Overtime-Services (Backend, WebSocket-Gateway, künftige Microservices) würde das Duplizieren sicherheitsrelevanter Pipeline-Schritte schnell zu Inkonsistenzen führen. Dieses ADR erklärt, warum CI-Bausteine zentral in einem gemeinsamen Templates-Repository gepflegt werden.
1. Kontext & Problemstellung (Deutsch)¶
Mit der wachsenden Anzahl an Repositories und Microservices innerhalb der Overtime-Plattform entsteht ein operationelles und sicherheitskritisches Risiko: der sogenannte Configuration Drift.
Wenn jeder Service seine sicherheitsrelevanten CI/CD-Schritte (wie SAST, Container-Scanning oder Image-Builds) individuell in einer eigenen .gitlab-ci.yml pflegt, führt dies zwangsläufig zu Inkonsistenzen. Ein Repository könnte veraltete Trivy-Versionen nutzen, ein anderes wichtige Code-Scans komplett überspringen oder falsche Schwellenwerte (Severity Thresholds) für das Blockieren von Builds definieren. Um eine revisionssichere und einheitliche Software-Lieferkette zu garantieren, müssen Security-Controls zentral verwaltet, versioniert und über alle Services hinweg gleichzeitig aktualisiert werden können.
2. Architecture Decision Record (English)¶
ADR-004: Centralized CI Pipeline Templates¶
Status¶
Accepted
Context and Problem Statement¶
As the number of services grows, duplicating security-relevant CI steps (scanning, SAST, image building) in each service's .gitlab-ci.yml creates drift: one repo may fall behind on Trivy versions, another may skip a scanner, a third may misconfigure severity thresholds. Security controls must be consistent, centrally updatable, and auditable.
Decision Drivers¶
- Uniform Security Gating: Security controls (scanning, SAST, secure builds) must be identical and enforced across all deployed services.
- Maintainability: A single version bump to a security tool (e.g., updating the Trivy scanner image) must propagate to all pipelines without requiring individual Pull/Merge Requests per service repository.
- Developer Velocity: Service teams should focus on service-specific implementation (unit tests, application code) rather than maintaining complex CI runner configurations and scanner wirings ("paved golden road").
- BSI IT-Grundschutz CON.8: Requirement for a repeatable, secure, and auditable software development and delivery process.
Considered Options¶
- Copy-paste per repo — Each
.gitlab-ci.ymlcontains full job definitions. There is no central dependency, but it causes massive duplication and inevitable configuration drift. - **GitLab CI
include: project**— CI jobs are defined once in a dedicated, shared repository and included by reference in the downstream microservices. - GitLab CI Components (Catalog) — A newer GitLab feature (>= 16.0) utilizing semantic versioning and strict interface contracts.
Decision Outcome¶
Chosen: **GitLab CI include: project** via a dedicated overtime-ci-templates repository.
Justification: GitLab CI Components were strongly considered but require specific GitLab 16+ features that may not be fully available or configured on all self-hosted enterprise instances. The include: project approach is battle-tested, stable on all supported GitLab versions, and immediately solves the configuration drift problem.
Consequences & Trade-offs¶
Positive Consequences¶
- Centralized Updates: Updating Trivy from
0.71.1to0.72.0requires exactly one commit to theovertime-ci-templatesrepository. All consuming pipelines automatically pick up the new security scanner on their next execution or when the referenced projects update the tag/sha with renovate. - Policy Enforcement: The Security/DevSecOps team can enforce minimum scanner versions or introduce new compliance checks globally by modifying the central template.
- Simplified Service Repositories: Consuming
.gitlab-ci.ymlfiles remain lean (approx. 10-20 lines instead of 150+) and only define service-specific variables or overrides.
Negative Consequences / Trade-offs¶
- Single Point of Failure: A bug/ breaking change in
overtime-ci-templates/may break all downstream service pipelines simultaneously. - Mitigation: The
overtime-ci-templatesrepository must be treated as a critical library. Merge Requests must be heavily reviewed and tested against a sample consuming pipeline before being merged. Pinning specific semantic version tags (e.g.,ref: v1.2.0) to enable controlled, staggered rollouts.
3. Pipeline Implementation & Repository Structure (English)¶
The central repository alexb-overtime/overtime-ci-templates serves as the single source of truth for all pipeline jobs. Consuming repositories integrate these jobs simply by declaring include: project: alexb-overtime/overtime-ci-templates.
Provided Templates¶
| File | Purpose |
|---|---|
build-docker.yml |
Rootless Buildah build + push (ADR-001) |
run-tests.yml |
Django test runner execution (uv + SQLite) |
lint.yml |
Ruff linting and strict formatting checks |
scan.yml |
Trivy SBOM + vulnerability + license + HTML report generation (ADR-003) |
sast.yml |
Semgrep SAST (Django, Python, OWASP, Docker rules) |
semantic-release.yml |
Automated semantic versioning and Git tag creation |
deploy-environments.yml |
Manual deployment gating buttons for test/prod environments |
update-gitops.yml |
Automated Kustomize image tag patching within the GitOps repository |
Example usage in a downstream microservice¶
include:
- project: "alexb-overtime/overtime-ci-templates"
ref: v1.2.0
file:
- "run-tests.yml"
- "lint.yml"
- "build-docker.yml"
- "scan.yml"
- "sign.yml"
- "sast.yml"
- "update-gitops.yml"
- "deploy-environments.yml"
- "semantic-release.yml"
...
trivy-deps-scan:
extends: .trivy-deps-scan
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: "$CI_COMMIT_BRANCH"
...
sbom:
extends: .sbom
variables:
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: "$CI_COMMIT_BRANCH"
trivy-vuln-scan:
extends: .trivy-vuln-scan
variables:
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: "$CI_COMMIT_BRANCH"
trivy-license-scan:
extends: .trivy-license-scan
variables:
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: "$CI_COMMIT_BRANCH"
trivy-html-report:
extends: .trivy-html-report
variables:
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: "$CI_COMMIT_BRANCH"
...
4. Compliance Einordnung (Deutsch)¶
BSI IT-Grundschutz Compliance¶
| Standard | Kriterium / Inhalt | Wie im Projekt adressiert |
|---|---|---|
| BSI IT-Grundschutz | CON.8.A11 (S): Erstellung einer Richtlinie für die Software-Entwicklung | Die zentralen Pipeline-Templates fungieren als technisch verbindliche Richtlinie (Policy-as-Code). Sie geben Entwicklern feste Elemente vor, die zwingend im Build-Prozess verwendet werden müssen. |
| BSI IT-Grundschutz | CON.8.A7 (B): Durchführung von entwicklungsbegleitenden Software-Tests | Durch die zentrale Aussteuerung ist technisch sichergestellt, dass die geforderte automatisierte statische Code-Analyse (SAST) und Tests vor jeder Freigabe (Quality Gates) zwingend ausgeführt werden. |
| BSI IT-Grundschutz | APP.4.4.A2 (B): Planung der Automatisierung mit CI/CD | Die Trennung zwischen Applikationscode und Pipeline-Logik (Templates) dokumentiert eine saubere, methodische Planung der CI/CD-Architektur und verhindert unkontrollierte Schatten-Pipelines. |