Files
stack/.woodpecker/harden.yml
kert 1ac93b62bf
Some checks are pending
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/deploy Pipeline is pending
ci/woodpecker/push/infra-ci Pipeline is pending
add bootstrap_secrets.py, fix harden pipeline rate limit
- dev/scripts/bootstrap_secrets.py: one-time setup of all secrets
  across .env, PostgreSQL, Gitea, and Woodpecker. Includes --verify.
- Remove pull_image:true from harden.yml (Docker Hub 429 rate limit)
- CI pipeline is build+scan+report only — no credential rotation
- Future rotation deferred to P18 milestone
2026-03-23 16:09:45 -04:00

145 lines
4.4 KiB
YAML

# ── Hardening pipeline ────────────────────────────────────────────
# Rebuilds all images with apt-get/apk upgrade, scans for vulns,
# and auto-closes Gitea vuln issues when scans are clean.
# Trigger: manual or weekly cron.
when:
- event: [manual, cron]
variables:
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
- &buildx_base
buildkit_config: |
[registry."gitea.homelab.fhirworx.io"]
http = true
registry: gitea.homelab.fhirworx.io
username:
from_secret: registry_user
password:
from_secret: registry_pass
- &trivy_scan
image: aquasec/trivy:latest
- &diag_env
UV_PYTHON_PREFERENCE: only-system
UV_LINK_MODE: copy
UV_PROJECT_ENVIRONMENT: .venv
GITEA_TOKEN:
from_secret: gitea_token
steps:
# ── Build hardened images ──────────────────────────────────
- name: build-notebooks
image: *buildx_image
settings:
<<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/notebooks
dockerfile: notebooks/Dockerfile
context: notebooks/
tags: [hardened, latest]
no_cache: true
- name: build-zotero
image: *buildx_image
settings:
<<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/zotero
dockerfile: zotero/Dockerfile
context: zotero/
tags: [hardened, latest]
no_cache: true
- name: build-docs
image: *buildx_image
settings:
<<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/docs
dockerfile: docs/Dockerfile
context: .
tags: [hardened, latest]
no_cache: true
- name: build-api
image: *buildx_image
settings:
<<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/api
dockerfile: api/Dockerfile
context: .
tags: [hardened, latest]
no_cache: true
- name: build-mc
image: *buildx_image
settings:
<<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/mc
dockerfile: rustfs/Dockerfile.mc
context: rustfs/
tags: [hardened, latest]
no_cache: true
# ── Scan hardened images ───────────────────────────────────
- name: scan-notebooks
<<: *trivy_scan
commands:
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
--exit-code 0 --format json -o notebooks-scan.json
"gitea.homelab.fhirworx.io/homelab/notebooks:hardened"
depends_on: [build-notebooks]
- name: scan-zotero
<<: *trivy_scan
commands:
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
--exit-code 0 --format json -o zotero-scan.json
"gitea.homelab.fhirworx.io/homelab/zotero:hardened"
depends_on: [build-zotero]
- name: scan-docs
<<: *trivy_scan
commands:
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
--exit-code 0 --format json -o docs-scan.json
"gitea.homelab.fhirworx.io/homelab/docs:hardened"
depends_on: [build-docs]
- name: scan-api
<<: *trivy_scan
commands:
- trivy image --image-src remote --insecure --severity HIGH,CRITICAL
--exit-code 0 --format json -o api-scan.json
"gitea.homelab.fhirworx.io/homelab/api:hardened"
depends_on: [build-api]
# ── Close resolved vuln issues OR file new ones ────────────
- name: close-or-report-vulns
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
environment:
<<: *diag_env
commands:
- uv sync --no-dev
- |
for f in notebooks-scan.json zotero-scan.json docs-scan.json api-scan.json; do
if [ -f "$f" ]; then
uv run python -m api.diag.vuln --close "$f" || \
uv run python -m api.diag.vuln "$f" || true
fi
done
depends_on:
- scan-notebooks
- scan-zotero
- scan-docs
- scan-api
# ── Failure reporter ─────────────────────────────────────────
- name: report-failure
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
failure: ignore
environment:
<<: *diag_env
commands:
- uv sync --no-dev
- uv run python -m api.diag
when:
- status: [failure]