Skip to content

security(render): prod render fetches third-party manifests unpinned, one from a moving branch #3196

Description

@devantler

🤖 Generated by the Agentic Engineer

Evidence

Measured 2026-08-17 while running the required prod authorization validator locally.

Two entries in the prod controllers render fetch third-party manifests over the network at render time:

  • k8s/providers/hetzner/infrastructure/controllers/origin-ca-issuer/kustomization.yaml:8-9 — two CRDs from Cloudflare's trunk branch (a moving branch, not a pin)
  • k8s/providers/hetzner/infrastructure/controllers/kubelet-serving-cert-approver/kustomization.yaml:21 — an install bundle pinned to tag v0.11.0 (a tag, no digest)

Both are active in the prod render (controllers/kustomization.yaml:43 and :45).

Observed today: raw.githubusercontent.com returned HTTP 429 on repeated attempts, and kubectl kustomize k8s/providers/hetzner/infrastructure/controllers aborted with accumulating resources ... 429: Too Many Requests. Four render-dependent tests in scripts/validate-eks-ci-role-policy failed identically on clean main and on a feature branch, which is what establishes the dependency as the cause rather than any change.

Problem

  1. The render is not reproducible. trunk can move between two renders of the same commit, so one commit can produce two different expectedRenderedSurfaceSHA values with nothing in this repository having changed. That is directly relevant to the aggregate-fingerprint churn tracked in The EKS authorization surface hash goes stale on every HelmRelease dependency bump #2768.
  2. Unreviewed third-party content reaches the prod authorization surface. The cert-approver install bundle contributes ServiceAccount / ClusterRole / (Cluster)RoleBinding documents to the very surface validate-eks-ci-role-policy exists to pin. A trunk move lands with no PR, no review, and no digest.
  3. A required security gate is hostage to a third-party CDN. While the fetch rate-limits, the authorization measurement cannot be produced at all — which is how this was found.

Expected

Prod renders resolve entirely from reviewed, digest-pinned content in this repository.

Precedent — the pattern already exists here

scripts/update-vendored-operators.sh vendors pinned upstream bundles with SHA-256 verification and reviewed Checkov dispositions (CDI, KubeVirt), and CI re-validates the committed bytes against the pinned digest via --validate-committed. These two remotes are the outliers, not a new problem needing a new mechanism.

Acceptance criteria

  • No kustomization.yaml reachable from a prod render path references a remote URL.
  • Both dependencies are vendored under version control, pinned by digest, and refreshed through a reviewed updater path, with CI validating the committed bytes against that pin.
  • The five authorization roots and k8s/clusters/prod render with no network access.
  • A regression check fails if a new remote URL is introduced into a render path.

Suggested decomposition

  1. A guard that fails when a render path references a remote URL — small, immediately valuable, and prevents a third outlier.
  2. Vendor the origin-ca-issuer CRDs — most urgent, because trunk is unpinned today.
  3. Vendor the kubelet-serving-cert-approver bundle — pinned to a tag, so lower risk than (2), but it is the one contributing authorization documents.

Rough size: M overall; child (1) is S.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    📥 Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions