1
Architecture
vr6syncro edited this page 2026-07-06 20:52:36 +02:00
Table of Contents
Architektur
ci-workflows ist eine Bibliothek wiederverwendbarer Forgejo-Workflows. Aufrufende
Repos referenzieren die Workflows via workflow_call; Secrets flieszen ausschlieszlich
per secrets: inherit vom (privaten) Caller.
Komponenten
| Datei | Rolle | Version |
|---|---|---|
.forgejo/workflows/security.yml |
Reusable Security-Scan, Basic-Profil | v2.2.1 |
.forgejo/workflows/security-hardened.yml |
Reusable Security-Scan, Hardened-Profil | v2.2.1 |
.forgejo/workflows/promotion-gate.yml |
Reusable Pflichtdatei-Gate (public-Org) | v1.0.0 |
.forgejo/workflows/ci.yml |
Self-CI / Regressions-Gate | — |
examples/security-caller.yml |
Vorlage fuer den thin caller | — |
Datenfluss
- Ein Caller-Repo triggert bei
push/pull_request/scheduleseinen thin caller. - Der thin caller ruft
security.yml@main(odersecurity-hardened.yml) viaworkflow_callauf und vererbt Secrets. - Die Scanner laufen (Trivy FS immer; im Hardened-Profil zusaetzlich OSV, Hadolint,
optional SAST; pip-audit nur bei
requirements*.txt, Node-audit nur bei Lockfile). - Der Report-Schritt zaehlt Findings (inkl. non-CVE-Vulns und committeter Secrets) und
bildet einen
sha256-Fingerprint des Fund-Zustands. - Bei Findings und
event != pull_requestwird ein Forgejo-Issue ge-upsertet (stabiler Titel, Duplikat-Closer, Auto-Close bei sauberem Scan). - Telegram/Matrix feuern nur bei neuem Issue oder geaendertem Fingerprint.
- Das Hardened-Profil legt zusaetzlich SARIF- und SBOM-Artefakte ab.
Diagramm
flowchart TD
subgraph caller["Aufrufendes Repo (thin caller)"]
C[".forgejo/workflows/security.yml<br/>uses: ci-workflows/...@main<br/>secrets: inherit"]
PGC["Promotion-Gate-Caller<br/>(public-Org-Repo)"]
end
subgraph lib["vr6syncro/ci-workflows (public)"]
SEC["security.yml<br/>BASIC v2.2.1"]
HARD["security-hardened.yml<br/>HARDENED v2.2.1"]
PG["promotion-gate.yml<br/>v1.0.0"]
CI["ci.yml<br/>Self-CI"]
end
subgraph scanners["Scanner"]
TRIVY["Trivy FS<br/>vuln/secret/misconfig/license"]
PIP["pip-audit"]
NODE["npm / pnpm audit"]
OSV["OSV-Scanner (G6)"]
HADO["Hadolint (G8)"]
SAST["SAST: Bandit/ShellCheck/cppcheck"]
end
subgraph out["Ausgaben"]
ISSUE["Forgejo-Issue-Upsert<br/>fp-Gating + Auto-Close"]
TG["Telegram"]
MX["Matrix"]
ART["Artefakte: SARIF (G5) + SBOM CycloneDX (G4)"]
end
C -->|workflow_call| SEC
C -.optional.-> HARD
PGC -->|workflow_call| PG
CI -.validiert vor Rollout.-> SEC
CI -.validiert vor Rollout.-> HARD
SEC --> TRIVY & PIP & NODE
HARD --> TRIVY & PIP & NODE & OSV & HADO & SAST
TRIVY & PIP & NODE & OSV & HADO & SAST --> ISSUE
ISSUE --> TG & MX
HARD --> ART
classDef libnode fill:#2d6cdf,stroke:#1b3a7a,color:#fff;
classDef scan fill:#e67e22,stroke:#8a4a12,color:#fff;
classDef output fill:#27ae60,stroke:#145a32,color:#fff;
classDef call fill:#7f8c8d,stroke:#4d5656,color:#fff;
class SEC,HARD,PG,CI libnode;
class TRIVY,PIP,NODE,OSV,HADO,SAST scan;
class ISSUE,TG,MX,ART output;
class C,PGC call;
Wichtige Invarianten (durch Self-CI erzwungen)
- Kein
secrets:-Block unterworkflow_call— Forgejo erlaubt dort nurinputs/outputs; einsecrets:-Block macht den Workflow unparsebar und bricht die Reusable flottenweit (Regression0932a7c). Secrets kommen ausschlieszlich viasecrets: inherit. - non-CVE-Vulns zaehlen (GHSA/PYSEC/RUSTSEC/GO/DLA/DSA/USN/ALAS/ELSA).
- committete Secrets zaehlen (
.Results[].Secrets[]). - Clean-Scan = 0 Findings darf nicht roten (pipefail-Regression
4586d50).