Zum Inhalt

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.yml contains 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.1 to 0.72.0 requires exactly one commit to the overtime-ci-templates repository. 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.yml files 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-templates repository 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.