A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
315 lines
9.5 KiB
YAML
315 lines
9.5 KiB
YAML
# Woodpecker CI Security Pipeline
|
|
# Dedizierte Security-Scans fuer DevSecOps
|
|
#
|
|
# Laeuft taeglich via Cron und bei jedem PR
|
|
|
|
when:
|
|
- event: cron
|
|
cron: "0 3 * * *" # Taeglich um 3:00 Uhr
|
|
- event: pull_request
|
|
|
|
clone:
|
|
git:
|
|
image: woodpeckerci/plugin-git
|
|
settings:
|
|
depth: 1
|
|
extra_hosts:
|
|
- macmini:192.168.178.100
|
|
|
|
steps:
|
|
# ========================================
|
|
# Static Analysis
|
|
# ========================================
|
|
|
|
semgrep-scan:
|
|
image: returntocorp/semgrep:latest
|
|
commands:
|
|
- semgrep scan --config auto --json -o semgrep-results.json . || true
|
|
- |
|
|
if [ -f semgrep-results.json ]; then
|
|
echo "=== Semgrep Findings ==="
|
|
cat semgrep-results.json | head -100
|
|
fi
|
|
when:
|
|
event: [pull_request, cron]
|
|
|
|
bandit-python:
|
|
image: python:3.12-slim
|
|
commands:
|
|
- pip install --quiet bandit
|
|
- bandit -r backend/ -f json -o bandit-results.json || true
|
|
- |
|
|
if [ -f bandit-results.json ]; then
|
|
echo "=== Bandit Findings ==="
|
|
cat bandit-results.json | head -50
|
|
fi
|
|
when:
|
|
event: [pull_request, cron]
|
|
|
|
gosec-go:
|
|
image: securego/gosec:latest
|
|
commands:
|
|
- gosec -fmt json -out gosec-consent.json ./consent-service/... || true
|
|
- gosec -fmt json -out gosec-billing.json ./billing-service/... || true
|
|
- echo "Go Security Scan abgeschlossen"
|
|
when:
|
|
event: [pull_request, cron]
|
|
|
|
# ========================================
|
|
# Secrets Detection
|
|
# ========================================
|
|
|
|
gitleaks-scan:
|
|
image: zricethezav/gitleaks:latest
|
|
commands:
|
|
- gitleaks detect --source . --report-format json --report-path gitleaks-report.json || true
|
|
- |
|
|
if [ -s gitleaks-report.json ]; then
|
|
echo "=== WARNUNG: Potentielle Secrets gefunden ==="
|
|
cat gitleaks-report.json
|
|
else
|
|
echo "Keine Secrets gefunden"
|
|
fi
|
|
|
|
trufflehog-scan:
|
|
image: trufflesecurity/trufflehog:latest
|
|
commands:
|
|
- trufflehog filesystem . --json > trufflehog-results.json 2>&1 || true
|
|
- echo "TruffleHog Scan abgeschlossen"
|
|
|
|
# ========================================
|
|
# Dependency Vulnerabilities
|
|
# ========================================
|
|
|
|
npm-audit:
|
|
image: node:20-alpine
|
|
commands:
|
|
- cd website && npm audit --json > ../npm-audit-website.json || true
|
|
- cd ../studio-v2 && npm audit --json > ../npm-audit-studio.json || true
|
|
- cd ../admin-v2 && npm audit --json > ../npm-audit-admin.json || true
|
|
- echo "NPM Audit abgeschlossen"
|
|
when:
|
|
event: [pull_request, cron]
|
|
|
|
pip-audit:
|
|
image: python:3.12-slim
|
|
commands:
|
|
- pip install --quiet pip-audit
|
|
- pip-audit -r backend/requirements.txt --format json -o pip-audit-backend.json || true
|
|
- pip-audit -r voice-service/requirements.txt --format json -o pip-audit-voice.json || true
|
|
- echo "Pip Audit abgeschlossen"
|
|
when:
|
|
event: [pull_request, cron]
|
|
|
|
go-vulncheck:
|
|
image: golang:1.21-alpine
|
|
commands:
|
|
- go install golang.org/x/vuln/cmd/govulncheck@latest
|
|
- cd consent-service && govulncheck ./... || true
|
|
- cd ../billing-service && govulncheck ./... || true
|
|
- echo "Go Vulncheck abgeschlossen"
|
|
when:
|
|
event: [pull_request, cron]
|
|
|
|
# ========================================
|
|
# Container Security
|
|
# ========================================
|
|
|
|
trivy-filesystem:
|
|
image: aquasec/trivy:latest
|
|
commands:
|
|
- trivy fs --severity HIGH,CRITICAL --format json -o trivy-fs.json . || true
|
|
- echo "Trivy Filesystem Scan abgeschlossen"
|
|
when:
|
|
event: cron
|
|
|
|
# ========================================
|
|
# SBOM Generation (taeglich)
|
|
# ========================================
|
|
|
|
daily-sbom:
|
|
image: anchore/syft:latest
|
|
commands:
|
|
- mkdir -p sbom-reports
|
|
- syft dir:. -o cyclonedx-json > sbom-reports/sbom-full-$(date +%Y%m%d).json
|
|
- echo "SBOM generiert"
|
|
when:
|
|
event: cron
|
|
|
|
# ========================================
|
|
# AUTO-FIX: Dependency Vulnerabilities
|
|
# Laeuft nur bei Cron (nightly), nicht bei PRs
|
|
# ========================================
|
|
|
|
auto-fix-npm:
|
|
image: node:20-alpine
|
|
commands:
|
|
- apk add --no-cache git
|
|
- |
|
|
echo "=== Auto-Fix: NPM Dependencies ==="
|
|
FIXES_APPLIED=0
|
|
|
|
for dir in website studio-v2 admin-v2 h5p-service; do
|
|
if [ -d "$dir" ] && [ -f "$dir/package.json" ]; then
|
|
echo "Pruefe $dir..."
|
|
cd $dir
|
|
|
|
# Speichere Hash vor Fix
|
|
BEFORE=$(md5sum package-lock.json 2>/dev/null || echo "none")
|
|
|
|
# npm audit fix (ohne --force fuer sichere Updates)
|
|
npm audit fix --package-lock-only 2>/dev/null || true
|
|
|
|
# Pruefe ob Aenderungen
|
|
AFTER=$(md5sum package-lock.json 2>/dev/null || echo "none")
|
|
if [ "$BEFORE" != "$AFTER" ]; then
|
|
echo " -> Fixes angewendet in $dir"
|
|
FIXES_APPLIED=$((FIXES_APPLIED + 1))
|
|
fi
|
|
|
|
cd ..
|
|
fi
|
|
done
|
|
|
|
echo "NPM Auto-Fix abgeschlossen: $FIXES_APPLIED Projekte aktualisiert"
|
|
echo "NPM_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env
|
|
when:
|
|
event: cron
|
|
|
|
auto-fix-python:
|
|
image: python:3.12-slim
|
|
commands:
|
|
- apt-get update && apt-get install -y git
|
|
- pip install --quiet pip-audit
|
|
- |
|
|
echo "=== Auto-Fix: Python Dependencies ==="
|
|
FIXES_APPLIED=0
|
|
|
|
for reqfile in backend/requirements.txt voice-service/requirements.txt klausur-service/backend/requirements.txt; do
|
|
if [ -f "$reqfile" ]; then
|
|
echo "Pruefe $reqfile..."
|
|
DIR=$(dirname $reqfile)
|
|
|
|
# pip-audit mit --fix (aktualisiert requirements.txt)
|
|
pip-audit -r $reqfile --fix 2>/dev/null || true
|
|
|
|
# Pruefe ob requirements.txt geaendert wurde
|
|
if git diff --quiet $reqfile 2>/dev/null; then
|
|
echo " -> Keine Aenderungen in $reqfile"
|
|
else
|
|
echo " -> Fixes angewendet in $reqfile"
|
|
FIXES_APPLIED=$((FIXES_APPLIED + 1))
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo "Python Auto-Fix abgeschlossen: $FIXES_APPLIED Dateien aktualisiert"
|
|
echo "PYTHON_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env
|
|
when:
|
|
event: cron
|
|
|
|
auto-fix-go:
|
|
image: golang:1.21-alpine
|
|
commands:
|
|
- apk add --no-cache git
|
|
- |
|
|
echo "=== Auto-Fix: Go Dependencies ==="
|
|
FIXES_APPLIED=0
|
|
|
|
for dir in consent-service billing-service school-service edu-search ai-compliance-sdk; do
|
|
if [ -d "$dir" ] && [ -f "$dir/go.mod" ]; then
|
|
echo "Pruefe $dir..."
|
|
cd $dir
|
|
|
|
# Go mod tidy und update
|
|
go get -u ./... 2>/dev/null || true
|
|
go mod tidy 2>/dev/null || true
|
|
|
|
# Pruefe ob go.mod/go.sum geaendert wurden
|
|
if git diff --quiet go.mod go.sum 2>/dev/null; then
|
|
echo " -> Keine Aenderungen in $dir"
|
|
else
|
|
echo " -> Updates angewendet in $dir"
|
|
FIXES_APPLIED=$((FIXES_APPLIED + 1))
|
|
fi
|
|
|
|
cd ..
|
|
fi
|
|
done
|
|
|
|
echo "Go Auto-Fix abgeschlossen: $FIXES_APPLIED Module aktualisiert"
|
|
echo "GO_FIXES=$FIXES_APPLIED" >> /tmp/autofix-results.env
|
|
when:
|
|
event: cron
|
|
|
|
# ========================================
|
|
# Commit & Push Auto-Fixes
|
|
# ========================================
|
|
|
|
commit-security-fixes:
|
|
image: alpine/git:latest
|
|
commands:
|
|
- |
|
|
echo "=== Commit Security Fixes ==="
|
|
|
|
# Git konfigurieren
|
|
git config --global user.email "security-bot@breakpilot.de"
|
|
git config --global user.name "Security Bot"
|
|
git config --global --add safe.directory /woodpecker/src
|
|
|
|
# Pruefe ob es Aenderungen gibt
|
|
if git diff --quiet && git diff --cached --quiet; then
|
|
echo "Keine Security-Fixes zum Committen"
|
|
exit 0
|
|
fi
|
|
|
|
# Zeige was geaendert wurde
|
|
echo "Geaenderte Dateien:"
|
|
git status --short
|
|
|
|
# Stage alle relevanten Dateien
|
|
git add -A \
|
|
*/package-lock.json \
|
|
*/requirements.txt \
|
|
*/go.mod \
|
|
*/go.sum \
|
|
2>/dev/null || true
|
|
|
|
# Commit erstellen
|
|
TIMESTAMP=$(date +%Y-%m-%d)
|
|
git commit -m "fix(security): auto-fix vulnerable dependencies [$TIMESTAMP]
|
|
|
|
Automatische Sicherheitsupdates durch CI/CD Pipeline:
|
|
- npm audit fix fuer Node.js Projekte
|
|
- pip-audit --fix fuer Python Projekte
|
|
- go get -u fuer Go Module
|
|
|
|
Co-Authored-By: Security Bot <security-bot@breakpilot.de>" || echo "Nichts zu committen"
|
|
|
|
# Push zum Repository
|
|
git push origin HEAD:main || echo "Push fehlgeschlagen - manueller Review erforderlich"
|
|
|
|
echo "Security-Fixes committed und gepusht"
|
|
when:
|
|
event: cron
|
|
status: success
|
|
|
|
# ========================================
|
|
# Report to Dashboard
|
|
# ========================================
|
|
|
|
update-security-dashboard:
|
|
image: curlimages/curl:latest
|
|
commands:
|
|
- |
|
|
curl -X POST "http://backend:8000/api/security/scan-results" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{
|
|
\"scan_type\": \"daily\",
|
|
\"timestamp\": \"$(date -Iseconds)\",
|
|
\"tools\": [\"semgrep\", \"bandit\", \"gosec\", \"gitleaks\", \"trivy\"]
|
|
}" || true
|
|
when:
|
|
status: [success, failure]
|
|
event: cron
|