feat(vuln): vuln-scanner platform manifests, Flux tier, alerts, L0/L2/L3 tests
Hand-authored platform/vuln-scanner (non-gating Flux tier, digest-pinned Trivy 0.76.1 and python 3.14.9-alpine, read-only RBAC, per-pod oauth2-proxy, internal-only cve.<domain>), five alerts with promtool tests, R-VULN-01..09 registry entries, and vuln-* L0 checks with mutation self-tests. src/ and the bot workflow are integrated separately. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
4c3a284cad
commit
b85d1e3ed7
47 files changed
+2572
-6
No files matched your search
@@ -78,6 +78,10 @@ resources:
|
||||
# `wg-server-key` Secret, so in the gating `platform` tier an unfinished manual step would have
|
||||
# stalled every apps wave. Carries no SOPS secret, so neither overlay adds a decryption patch.
|
||||
- vpn-ingress.yaml # Flux Kustomization -> ./platform/vpn-ingress (dependsOn platform-config)
|
||||
# CVE visibility scanner (docs/17, ADR-0027) — POST-platform tier (dependsOn platform-config,
|
||||
# wait:false): a failing scanner must never gate the platform, and nothing dependsOn it. Carries the
|
||||
# oauth2-proxy credential SOPS file, so both overlays add a decryption patch by name.
|
||||
- vuln-scanner.yaml # Flux Kustomization -> ./platform/vuln-scanner (dependsOn platform-config)
|
||||
# Cloudflare Tunnel connector (north-south INGRESS from the Cloudflare edge) — POST-platform tier
|
||||
# (dependsOn platform-config, wait:false), and NOTHING dependsOn it. Non-gating is load-bearing,
|
||||
# as for vpn-ingress: the Deployment cannot become Ready until the operator enrols the tunnel
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# Flux Kustomization: the CVE visibility scanner (docs/17, ADR-0027) — reconciles ./platform/vuln-scanner.
|
||||
#
|
||||
# ISOLATION IS THE POINT, as for clusters/base/cloudflared.yaml. A failing scanner, an unbound PVC or a
|
||||
# pending Certificate must never become a stalled platform, so:
|
||||
# * ITS OWN Kustomization, not a line in platform/kustomization.yaml;
|
||||
# * wait: false — its health is reported by the VulnScanStale/VulnDatabaseStale/VulnCoverageGap/
|
||||
# VulnCriticalFixAvailable/VulnTriageBotSilent alerts (platform/vuln-scanner/alerts.yaml), not by
|
||||
# this object's Ready condition, which reaches Ready on apply success;
|
||||
# * NOTHING dependsOn THIS. conformance/tests/l0-static/vuln-scanner-isolation fails the gate if any
|
||||
# Kustomization gains `dependsOn: vuln-scanner` or this one stops being wait:false.
|
||||
#
|
||||
# dependsOn: [platform-config] — a real edge: PrometheusRule/ServiceMonitor/Gateway API CRDs, the
|
||||
# Longhorn StorageClass, the Gateway, Keycloak's realm, and Longhorn itself come up through
|
||||
# `platform`/`platform-config` first.
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: vuln-scanner
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
retryInterval: 2m
|
||||
timeout: 5m
|
||||
prune: true
|
||||
wait: false
|
||||
dependsOn:
|
||||
- name: platform-config
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: flux-system
|
||||
path: ./platform/vuln-scanner
|
||||
# REQUIRED: the HTTPRoute hostname, the oauth2-proxy issuer/redirect/cookie-domain args and every
|
||||
# alert's runbook_url are written `${BASE_DOMAIN}`. Substitution fails OPEN, so the file
|
||||
# conformance/tests/l0-static/flux-postbuild-substitution audits this tier.
|
||||
postBuild:
|
||||
substituteFrom:
|
||||
- kind: ConfigMap
|
||||
name: cluster-vars
|
||||
# SOPS decryption is layered per-environment: clusters/dev and clusters/prod each patch THIS
|
||||
# Kustomization by name with a `decryption:` stanza for the oauth2-proxy credentials.
|
||||
@@ -140,6 +140,21 @@ patches:
|
||||
provider: sops
|
||||
secretRef:
|
||||
name: sops-age
|
||||
# vuln-scanner (the CVE visibility scanner, clusters/base/vuln-scanner.yaml) carries
|
||||
# platform/vuln-scanner/vuln-scanner-oauth2-proxy-credentials.sops.yaml — the per-pod oauth2-proxy
|
||||
# client and cookie secrets. Without this stanza the Secret applies full of ENC[...] and the
|
||||
# sidecar cannot authenticate; the rest of the scanner runs regardless. `sops-age` is out-of-band.
|
||||
- patch: |-
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: vuln-scanner
|
||||
namespace: flux-system
|
||||
spec:
|
||||
decryption:
|
||||
provider: sops
|
||||
secretRef:
|
||||
name: sops-age
|
||||
# cloudflared (the Cloudflare Tunnel connector, clusters/base/cloudflared.yaml) carries
|
||||
# platform/cloudflared/cloudflared-credentials.sops.yaml — the tunnel credentials JSON, the one
|
||||
# secret in that component. Without this stanza the Secret applies full of ENC[...]: the APPLY
|
||||
|
||||
@@ -131,6 +131,21 @@ patches:
|
||||
provider: sops
|
||||
secretRef:
|
||||
name: sops-age
|
||||
# vuln-scanner (the CVE visibility scanner, clusters/base/vuln-scanner.yaml) carries
|
||||
# platform/vuln-scanner/vuln-scanner-oauth2-proxy-credentials.sops.yaml — the per-pod oauth2-proxy
|
||||
# client and cookie secrets. Without this stanza the Secret applies full of ENC[...] and the
|
||||
# sidecar cannot authenticate; the rest of the scanner runs regardless. `sops-age` is out-of-band.
|
||||
- patch: |-
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: vuln-scanner
|
||||
namespace: flux-system
|
||||
spec:
|
||||
decryption:
|
||||
provider: sops
|
||||
secretRef:
|
||||
name: sops-age
|
||||
# cloudflared (the Cloudflare Tunnel connector, clusters/base/cloudflared.yaml) carries
|
||||
# platform/cloudflared/cloudflared-credentials.sops.yaml — the tunnel credentials JSON, the one
|
||||
# secret in that component. Without this stanza the Secret applies full of ENC[...]: the APPLY
|
||||
|
||||
Reference in new issue
Block a user