mirror of
https://github.com/enix/x509-certificate-exporter.git
synced 2026-08-23 22:16:39 +00:00
Complete rewrite of the codebase, the build pipeline, the dev loop, and the release pipeline. For the exporter itself, refer to the updated README and Helm chart documentation to discover the new functionality and assess the impact of the breaking changes on your existing setup. Build & release: - QA/CI pipelines now run through a Dagger Module, wrapped by Taskfile.yml for the developer interface. - Releases run through GoReleaser: cross-compiled binaries × OS/arch, archives, checksums, multi-arch container images (busybox + scratch variants on linux/amd64,arm64,riscv64), pushed to ghcr/quay/docker.io. - Everything is cosign-signed (binaries, images, Helm chart). Image CycloneDX SBOMs are attached as cosign attestations. SLSA-3 provenance is attached to every GitHub Release. - The Helm chart is published as a cosign-signed OCI artifact. - Versioning and changelog are automated by release-please from Conventional Commits. Dev experience: - Local loop driven by Tilt + k3d + Dagger; one command brings up an exporter with seeded fixtures and a Prometheus scraping it. - End-to-end tests run on a throwaway k3d cluster against the real rendered chart. BREAKING CHANGE: the Helm chart is now published exclusively as an OCI artifact at oci://quay.io/enix/charts/x509-certificate-exporter. The legacy Helm repository at https://charts.enix.io is no longer updated; users must switch to the OCI reference (Helm 3.8+ required). Installation: `helm install x509-certificate-exporter oci://quay.io/enix/charts/x509-certificate-exporter --version <vX.Y.Z>`. BREAKING CHANGE: the Helm chart's values schema may diverge from v3 in edge cases despite a best-effort to preserve backwards compatibility. Review your existing values against the updated chart/values.yaml before upgrading. A JSON schema (chart/values.schema.json) is shipped with the chart so `helm install` / `helm upgrade` will reject any values that no longer match the expected shape, surfacing regressions early instead of at runtime. BREAKING CHANGE: Alpine-based container images are no longer published. The release pipeline now ships only the `busybox` and `scratch` variants on linux/amd64,arm64,riscv64. Users pulling `*-alpine` tags must switch to one of the new variants — `busybox` is the closest functional replacement (still has a shell), `scratch` is the minimal distroless option.
80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// Govulncheck runs Go's reachability-based CVE scanner. The
|
|
// vulnerability database is fetched from vuln.go.dev at run time —
|
|
// dataset is never stale. The analyzer itself tracks @latest;
|
|
// tamper-resistance is via the Go module proxy + checksum DB.
|
|
func (m *X509Ce) Govulncheck(ctx context.Context) (string, error) {
|
|
return goBase(m.Source).
|
|
WithExec([]string{"go", "install", "golang.org/x/vuln/cmd/govulncheck@" + govulncheckPath}).
|
|
WithExec([]string{"govulncheck", "./..."}).
|
|
Stdout(ctx)
|
|
}
|
|
|
|
// Trivy runs Aqua Security's Trivy scanner against the working tree.
|
|
// One function, two scan families:
|
|
//
|
|
// - scanType=fs → filesystem scan: detects vulnerabilities in
|
|
// Go module deps, lockfiles, OS packages,
|
|
// etc. Use for dependency CVE checks.
|
|
// - scanType=config → IaC misconfig scan: catches security
|
|
// misconfigurations in Helm / Kubernetes /
|
|
// Dockerfile / Terraform manifests. Use
|
|
// against `chart/`.
|
|
//
|
|
// Threshold is HIGH,CRITICAL with a non-zero exit on any finding.
|
|
// The Trivy DB cache is mounted as a Dagger CacheVolume so successive
|
|
// runs don't re-download (~50 MB).
|
|
func (m *X509Ce) Trivy(
|
|
ctx context.Context,
|
|
// Scan family: "fs" or "config".
|
|
scanType string,
|
|
// Path inside the source to scan. Use "." (default) for whole-repo
|
|
// fs scans, or e.g. "chart" for a chart-only config scan.
|
|
// +optional
|
|
// +default="."
|
|
scanRef string,
|
|
// For "fs" scans: skip CVEs whose upstream has no patch yet —
|
|
// avoids alert fatigue on findings nobody can act on. Ignored for
|
|
// "config" scans. Default matches the previous CI policy.
|
|
// +optional
|
|
// +default=true
|
|
ignoreUnfixed bool,
|
|
) (string, error) {
|
|
switch scanType {
|
|
case "fs", "config":
|
|
default:
|
|
return "", fmt.Errorf(`unknown scan type %q (expected "fs" or "config")`, scanType)
|
|
}
|
|
|
|
args := []string{
|
|
"trivy", scanType,
|
|
"--severity", "HIGH,CRITICAL",
|
|
"--exit-code", "1",
|
|
// Always points at the repo-root .trivyignore. Trivy's default
|
|
// is to look in the scan root, which changes with --scan-ref —
|
|
// pinning it explicitly here keeps suppressions in one place.
|
|
"--ignorefile", "/src/.trivyignore",
|
|
}
|
|
if scanType == "fs" && ignoreUnfixed {
|
|
args = append(args, "--ignore-unfixed")
|
|
}
|
|
target := "/src"
|
|
if scanRef != "" && scanRef != "." {
|
|
target = "/src/" + scanRef
|
|
}
|
|
args = append(args, target)
|
|
|
|
return dag.Container().
|
|
From(trivyImage).
|
|
WithMountedCache("/root/.cache/trivy", dag.CacheVolume("trivy")).
|
|
WithDirectory("/src", m.Source).
|
|
WithExec(args).
|
|
Stdout(ctx)
|
|
}
|