# Internet-Facing Stack Lifecycle & Vulnerability Management _Last updated: 2026-04-07 (UTC)_ ## 1) Internet-facing application inventory (app, version, image digest) > Source of truth for internet-facing targets: `results/*` host folders and their WhatWeb outputs. > Operational owner must replace all `TBD` digest values with runtime evidence from `docker image inspect`/`docker ps --no-trunc`. | Host/FQDN | Product/App | Deployed version evidence | Container image (repo:tag) | Image digest (sha256) | Evidence source | |---|---|---|---|---|---| | auth.lan.ddnsgeek.com | Authelia (auth portal) | Version not fingerprinted from external scan | TBD | TBD | `results/auth.../tcp_443_https_whatweb.txt` | | edge.lan.ddnsgeek.com | Edge reverse-proxy/app entrypoint | Version not fingerprinted from external scan | TBD | TBD | `results/edge.../tcp_443_https_whatweb.txt` | | familytree.lan.ddnsgeek.com | FamilyTree app (gunicorn-backed) | gunicorn detected, app version not fingerprinted | TBD | TBD | `results/familytree.../tcp_443_https_whatweb.txt` | | gitea.lan.ddnsgeek.com | Gitea | Gitea detected; exact version not fingerprinted | TBD | TBD | `results/gitea.../tcp_443_https_whatweb.txt` | | gotify.lan.ddnsgeek.com | Gotify | Version not fingerprinted from external scan | TBD | TBD | `results/gotify.../tcp_443_https_whatweb.txt` | | grafana.lan.ddnsgeek.com | Grafana | Grafana login redirect observed; exact version not fingerprinted | TBD | TBD | `results/grafana.../tcp_443_https_whatweb.txt` | | influxdb.lan.ddnsgeek.com | InfluxDB (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/influxdb.../tcp_443_https_whatweb.txt` | | kuma.lan.ddnsgeek.com | Uptime Kuma | Dashboard redirect observed; exact version not fingerprinted | TBD | TBD | `results/kuma.../tcp_443_https_whatweb.txt` | | monitor-kuma.lan.ddnsgeek.com | Uptime Kuma (monitoring endpoint) | Dashboard redirect observed; exact version not fingerprinted | TBD | TBD | `results/monitor-kuma.../tcp_443_https_whatweb.txt` | | nextcloud.lan.ddnsgeek.com | Nextcloud (Apache/PHP stack) | Apache 2.4.66, PHP 8.3.30 | TBD | TBD | `results/nextcloud.../tcp_443_https_whatweb.txt` | | node-red.lan.ddnsgeek.com | Node-RED (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/node-red.../tcp_443_https_whatweb.txt` | | passbolt.lan.ddnsgeek.com | Passbolt | NGINX detected; exact Passbolt version not fingerprinted | TBD | TBD | `results/passbolt.../tcp_443_https_whatweb.txt` | | portainer.lan.ddnsgeek.com | Portainer | Portainer detected; exact version not fingerprinted | TBD | TBD | `results/portainer.../tcp_443_https_whatweb.txt` | | prometheus.lan.ddnsgeek.com | Prometheus (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/prometheus.../tcp_443_https_whatweb.txt` | | searxng.lan.ddnsgeek.com | SearXNG | `searxng/2026.4.5+474b0a55b` detected | TBD | TBD | `results/searxng.../tcp_443_https_whatweb.txt` | | shifts.lan.ddnsgeek.com | Shifts app (nginx front-end) | nginx 1.29.7 | TBD | TBD | `results/shifts.../tcp_443_https_whatweb.txt` | | stockfill.lan.ddnsgeek.com | Stockfill app (nginx front-end) | nginx 1.27.5 | TBD | TBD | `results/stockfill.../tcp_443_https_whatweb.txt` | | traefik.lan.ddnsgeek.com | Traefik (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/traefik.../tcp_443_https_whatweb.txt` | ### Required evidence commands (run on Docker host) ```bash # Capture deployed containers with immutable image digest references sudo docker ps --format '{{.Names}}\t{{.Image}}' --no-trunc # Resolve image digests for inventory table sudo docker image inspect --format '{{index .RepoDigests 0}}' # Optional: export inventory as CSV for compliance tracking sudo docker ps --format '{{.Names}},{{.Image}}' --no-trunc > internet-facing-runtime-images.csv ``` --- ## 2) Monthly update window definition ## Standard cadence - **Window:** Second Tuesday of every month, **02:00–06:00 UTC**. - **Fallback window:** Second Wednesday of every month, **02:00–06:00 UTC**. - **Emergency patch window (critical CVE only):** within **48 hours** of advisory triage. ## Scope per window 1. **OS packages** (host + VM base images): apply security and bugfix updates. 2. **Container base images**: rebuild/pull fresh immutable digests. 3. **Application releases**: patch/minor upgrades for internet-facing apps. ## Freeze and exception policy - No deferral beyond one cycle without documented risk acceptance. - Critical internet-facing CVEs (remote exploitable) cannot wait for the next regular window. --- ## 3) Pre-production smoke checks for critical apps All updates must be promoted through pre-prod first. Minimum smoke checks: ### Nextcloud - Login page loads. - Test user login succeeds. - File upload + download round trip succeeds. - Background jobs/cron status healthy. ### Passbolt - Login page loads. - Browser extension/API auth succeeds. - Secret create/read/update works for test vault. - Email/notification queue healthy. ### Gitea - Login succeeds. - Repository clone + push with test repo succeeds. - Webhook test delivery succeeds. - Actions/runner (if enabled) executes sample workflow. ### Grafana - Login succeeds. - Datasource health checks pass. - Key dashboards render without panel errors. - Alert rule evaluation pipeline healthy. ### Shared gate for all critical apps - HTTPS endpoint returns expected status. - No new high/critical findings in pre-prod vulnerability scan. - Error budget/SLO smoke threshold respected for 30 minutes post-deploy. --- ## 4) CVE advisory tracking mapped to deployed versions Create/maintain a single register (`cve-register.csv` or ticket board) with these required fields: - Product - Deployed version - Deployed image digest - CVE ID - CVSS score/severity - Advisory source URL - Affected version range - Exploit status (known exploited: yes/no) - Mitigation owner - Target fix version - Due date - Status (Open / In-progress / Pending validation / Resolved) ### Advisory sources (minimum) - Vendor advisories/release notes for each product (Nextcloud, Passbolt, Gitea, Grafana, etc.) - NVD - CISA KEV catalog (for known exploited CVEs) ### Mapping rule A CVE can only be marked “Not Affected” when the deployed version + digest is proven outside vulnerable ranges with evidence attached. --- ## 5) Closure evidence requirement (hard gate) A vulnerability ticket is only closed when **both** conditions are met: 1. **Version or digest changed in production** - Before/after evidence attached (`docker image inspect`, deployment manifest diff, or SBOM diff). 2. **Post-update scan is clean for that CVE** - Re-scan target service and attach artifact proving CVE no longer detected. ### Mandatory closure artifacts - Screenshot/export of runtime version and image digest after deployment. - Linked change request/deployment ID. - Post-update vulnerability scan report. - Smoke-test checklist execution evidence. ### Status workflow `Open -> Planned -> In Progress -> Pending Validation -> Resolved` `Resolved` is prohibited unless both hard-gate conditions above are satisfied.