Skip to content

Security: PastureStack/kubectl-service

SECURITY.md

Security Policy

Supported state

This repository provides a compatibility candidate for the isolated PastureStack migration environment. Do not deploy a locally modified or unverified image.

Security boundaries

  • Catalog event and reply bodies can contain credentials or chart data and must not be logged.
  • Chart paths must remain confined to a newly created mode-0700 temporary directory. Files are created exclusively as mode-0600 regular files; traversal, backslashes, ambiguous root charts, more than 4,096 files, files larger than 8 MiB, and total chart content larger than 64 MiB are rejected before Helm runs.
  • Namespace cleanup never sends requests to an arbitrary configured URL. PLATFORM_KUBERNETES_SERVER, SERVER, and KUBE_SERVER are mapped to a fixed set of internal origins; embedded credentials, custom paths, invalid Kubernetes namespace labels, and all HTTP redirects are rejected. Response bodies and untrusted stack names are not copied into operation logs.
  • The health listener uses an isolated HTTP mux and bounded server timeouts.
  • The main runtime and interactive shell broker execute as numeric UID/GID 65534:65534. The shell broker uses a distinct mode-0700 temporary home and kubeconfig for every session, removes it on exit, and requires neither privileged mode nor Linux capabilities. Catalog packaging must retain no-new-privileges, drop every capability, use a read-only shell-broker root filesystem, and provide only a bounded /tmp tmpfs.
  • The runtime CA bootstrap never modifies /etc, the system trust store, or a root-owned path. It copies the system bundle into a mode-0600 user-owned bundle, appends only a balanced public PEM certificate bundle, rejects private keys, and replaces the output atomically. Operators that need a historical certificate location must map it explicitly through PLATFORM_CA_ROOT; no hidden fallback is selected.
  • The pinned Helm 2.17.0 client and Tiller are a known legacy risk. Both are rebuilt with Go 1.26.5 from a verified source commit and a checksum-pinned patch that removes unnecessary broad dependencies. Tiller does not load the unused cloud-login plug-in bundle, retains /metrics through prometheus/client_golang v1.24.1, and contains no linked github.com/dgrijalva/jwt-go module. Tiller runs as UID/GID 10001 and the Kubernetes package enforces a read-only root filesystem, no privilege escalation, and no Linux capabilities. It must remain limited to the isolated compatibility environment.
  • The Helm 2 client and Tiller use PastureStack build version v2.17.1 from upstream v2.17.0. Each executable is built twice with empty build metadata, compared byte for byte, and checked against its own locked SHA-256; build and upstream versions are recorded separately.
  • The official Kubernetes 1.12.10 kubectl binary is extracted only after the server archive matches the pinned SHA-512 value.
  • The build container copies Docker CLI 29.6.2 from the Docker Official Image pinned to multi-platform manifest digest sha256:be132a9f282288de4afaf63379dff75711fda0147c6b72a9df44e51841402144. It does not download or execute an unchecked Docker static archive.
  • Every Ubuntu APT operation uses Canonical's snapshot 20260808T000000Z and an exact package=version entry from package/ubuntu-apt.lock. The original Ubuntu archive and security sources are upgraded to HTTPS; custom mutable mirrors are not accepted. The digest-pinned Docker Official Image supplies only the bootstrap CA bundle needed to reach the signed snapshot, after which the exact Ubuntu ca-certificates package replaces it. Each builder and runtime records the full installed Debian package set plus the snapshot ID in a tab-separated manifest, and the manual security gate hashes those manifests together with the CycloneDX and scan evidence.
  • The build container copies Buildx v0.36.1 only from its digest-pinned official image and verifies its embedded source commit. Trivy v0.73.1 is rebuilt with Go 1.26.5 from an immutable, checksum-locked upstream v0.73.0 source commit instead of copying the published executable. A checksum-locked module-files-only patch advances oras.land/oras-go/v2 from vulnerable v2.6.1 to v2.6.2 and github.com/go-git/go-git/v5 from vulnerable v5.19.1 to v5.19.2, removing High CVE-2026-71556; the source license and complete embedded Go build information are retained in the Dapper image. See build-tools/README.md.
  • Product compilation is explicitly CGO_ENABLED=0, but the CI race detector requires CGO. Dapper therefore contains the snapshot-locked GCC 4:15.2.0-5ubuntu1 metapackage, glibc development files, and Linux userspace API headers only for go test -race; none of those packages is copied into a product image. The Dapper raw scan, exact package inventory, and build-environment-only VEX assessment must be regenerated whenever this toolchain, snapshot, lock, or Ubuntu base changes.
  • The raw Buildx scan reports three High findings against the legacy github.com/docker/docker module. A source-level dependency audit proves that Buildx compiles only pkg/namesgenerator from that module; the affected Docker daemon authorization, archive, mount, and docker cp paths are absent. The release-specific machine-readable assessment is stored in security/openvex.json. Re-run both the raw scan and the VEX-applied scan whenever the Buildx version, source commit, or dependency graph changes.
  • Every release image records the full source commit in the OCI revision label. scripts/release requires a clean tree, exactly one annotated numeric SemVer tag (vMAJOR.MINOR.PATCH) at HEAD, and a tag target equal to the recorded revision. Brand, build-metadata, prerelease, and local-dirty suffixes are not valid artifact versions.
  • The manually dispatched Manual security release gate is verification-only and cannot deploy or publish an image. It runs with read-only repository permissions, checks out complete history without persisted credentials, builds all three product images, executes the full race and compatibility suite, scans source and images, applies the reviewed Dapper OpenVEX statement, emits CycloneDX plus exact Ubuntu APT lock and installed-package evidence, and retains only the small evidence bundle for seven days. Every referenced GitHub-authored action is pinned to a verified full commit SHA; the workflow has no push, pull-request, schedule, package-write, or deployment trigger.
  • Helm 3, Helm 4, the archived helm-2to3 source, and the current Kubernetes migration target are version- and commit-locked in migration/targets.lock.env. All 24 consecutive Kubernetes upgrade checkpoints are additionally version-, commit-, lifecycle-, and archive-hash-locked in migration/kubernetes-upgrade-path.tsv. Online verification compares the upstream checksum metadata, immutable source archives, exact tag commits, and source licenses. Download verification fetches source and reviewed patches only; it never downloads the known-vulnerable published Helm 3, Helm 4, or helm-2to3 executables.
  • The published Helm v3.21.3 executable is prohibited because it embeds High CVE-2026-50163 in oras.land/oras-go/v2 v2.6.1 and High CVE-2026-56852 in golang.org/x/text v0.38.0. The bridge is rebuilt as PastureStack build v3.21.4 from the immutable upstream v3.21.3 commit 1ad6e68924fdf6fb0c7dcef8e9e1dfc0f36eaed6 with Go 1.26.5 and a checksum-locked, module-files-only patch to ORAS v2.6.2 and x/text v0.39.0. Its license, complete module graph, deterministic output SHA-256, and build information are retained in the dedicated migration image; the build version is not an upstream Helm release claim.
  • The published archived helm-2to3 v0.11.0 executable is prohibited. A binary scan found 3 Critical and 43 High findings, including Critical CVE-2024-41110, CVE-2025-68121, and CVE-2026-33186. The replacement is PastureStack build v0.11.1, rebuilt from immutable upstream v0.11.0 commit 98df8bee4094de2e81c0507108867d8139d1306b with Go 1.26.5, Helm v3.21.3, ORAS v2.6.2, x/text v0.39.0, and the checksum-locked resolved module graph. The build runs all available package tests, performs two independent offline builds, rejects non-identical output, and locks the rebuilt binary SHA-256.
  • Helm 3 and helm-2to3 are packaged only in the separate source-rebuilt migration image. That image runs as UID/GID 10001, fails closed through /usr/bin/false unless an operator supplies an explicit tool entrypoint, and carries explicit-only and upstream-binaries=prohibited OCI labels. Packaging requires a Trivy binary-and-OS scan with zero Critical or High findings and emits a CycloneDX SBOM. The normal kubectl-service and Tiller runtimes do not contain either migration executable.
  • The final migration runtime removes Ubuntu's unrelated /usr/bin/pebble helper. Its embedded Go 1.26.4 and golang.org/x/net v0.40.0 would otherwise reintroduce five High findings (CVE-2026-25681, CVE-2026-27136, CVE-2026-33814, CVE-2026-39821, and CVE-2026-39822), even though neither migration executable contains those affected versions.
  • The Helm 4 runtime is opt-in and never selected by probing cluster state. The official upstream v4.2.3 source archive, exact tag commit, Apache-2.0 license, upstream security patch commit, upstream patch, and tag-compatible applied patch are independently checksum-locked. Helm had merged the two-file oras.land/oras-go/v2 v2.6.2 update after the release; PastureStack applies the same four module-file substitutions and rebuilds it as v4.2.4 with Go 1.26.5 because the published v4.2.3 binary embeds vulnerable v2.6.1. Upstream and build versions are recorded separately; v4.2.4 is not an upstream Helm release claim. Both patch representations are rejected unless they modify only go.mod and go.sum and contain the locked old and new ORAS versions. The rebuilt executable SHA-256, build-time dependency tests, embedded module evidence, and release-image scan must prove that High CVE-2026-50163 (GHSA-fxhp-mv3v-67qp) is absent. Helm upstream v4.2.3 is also outside the affected >=4.0.0, <=4.1.3 ranges for Critical GHSA-q5jf-9vfq-h4h7 and High GHSA-vmx8-mqv2-9gmg. The locked Helm 3 upstream source v3.21.3 is outside the affected ranges for High GHSA-557j-xg8c-q2mm. These checks do not authorize plug-in installation or dynamic network fetches inside the control plane.
  • Helm 4 release listing is bounded at 10,000 records. Empty or invalid identities and revisions are rejected; deleting a release without a caller-supplied namespace can uninstall the uniquely discovered release but cannot delete that namespace. Invalid backend configuration stops startup before event processing.
  • Release packaging verifies the image's numeric default user, exercises Helm 2 and Helm 4 under a read-only root filesystem with all capabilities dropped, and opens a complete interactive shell session through the unprivileged broker. A release is blocked if the session token remains in the interactive environment or its temporary home survives the session.
  • Do not commit API keys, kubeconfigs, certificates, chart secrets, private registry coordinates, or live event payloads.

Reporting

Report suspected vulnerabilities through this repository's private security advisory channel. Do not include live credentials or production event data in a public issue.

There aren't any published security advisories