From cdaf0090e09fa2005eaa4e78961c100e55b19ade Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Sat, 18 Jul 2026 22:40:04 +0200 Subject: [PATCH 1/4] fix(apps): pin tenant OCI manifest tags --- k8s/bases/apps/ascoachingogvaner/oci-repository.yaml | 2 +- k8s/bases/apps/wedding-app/oci-repository.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/k8s/bases/apps/ascoachingogvaner/oci-repository.yaml b/k8s/bases/apps/ascoachingogvaner/oci-repository.yaml index 88c66ddee..dc1c1ce0b 100644 --- a/k8s/bases/apps/ascoachingogvaner/oci-repository.yaml +++ b/k8s/bases/apps/ascoachingogvaner/oci-repository.yaml @@ -9,7 +9,7 @@ metadata: spec: interval: 1m ref: - semver: ">=1.0.0" + tag: 1.1.0 url: oci://ghcr.io/devantler-tech/ascoachingogvaner/manifests secretRef: name: ghcr-auth diff --git a/k8s/bases/apps/wedding-app/oci-repository.yaml b/k8s/bases/apps/wedding-app/oci-repository.yaml index e6af33828..43143e8a1 100644 --- a/k8s/bases/apps/wedding-app/oci-repository.yaml +++ b/k8s/bases/apps/wedding-app/oci-repository.yaml @@ -9,7 +9,7 @@ metadata: spec: interval: 1m ref: - semver: ">=1.0.0" + tag: 1.5.9 url: oci://ghcr.io/devantler-tech/wedding-app/manifests secretRef: name: ghcr-auth From fe394ecfaa033b86ee529293a210f66a6ee113b2 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Sun, 16 Aug 2026 08:42:19 +0200 Subject: [PATCH 2/4] fix(apps): approve the rendered surface for pinned tenant OCI tags Pinning the ascoachingogvaner and wedding-app OCIRepository refs moves the aggregate authorization-surface fingerprint, because Flux source resources are authorization-capable and their projected text is covered by it. Membership is unchanged and no per-resource hash moved; the delta is two spec.ref fields swapping a floating semver range for a fixed tag, which narrows what may be reconciled. Fingerprint read from the required job on the approved renderer, measured after updating onto current main. --- scripts/validate-eks-ci-role-policy/main.go | 34 ++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/scripts/validate-eks-ci-role-policy/main.go b/scripts/validate-eks-ci-role-policy/main.go index 5e9a16bae..7bb097d04 100644 --- a/scripts/validate-eks-ci-role-policy/main.go +++ b/scripts/validate-eks-ci-role-policy/main.go @@ -506,7 +506,39 @@ const ( // groups prevents an OIDC cluster-reader from recovering those credentials; // no identity, binding, resource, or verb is added. A parsed-RBAC regression // independently rejects any future read grant to either secret-bearing group. -const expectedRenderedSurfaceSHA = "03da7c1b972490eb9a4a4eecdffcd02e1b31c8ebb3dde3f4790f35f499837552" +// +// This value covers pinning the two tenant OCI manifest sources (#2737). The +// branch's complete delta against exact current main is TWO files, one line +// each, and nothing else: +// +// source.toolkit.fluxcd.io/v1 OCIRepository ascoachingogvaner/ascoachingogvaner +// spec.ref.semver: ">=1.0.0" (removed) +// spec.ref.tag: 1.1.0 (added) +// +// source.toolkit.fluxcd.io/v1 OCIRepository wedding-app/wedding-app +// spec.ref.semver: ">=1.0.0" (removed) +// spec.ref.tag: 1.5.9 (added) +// +// Both are Flux source resources, so they are authorization-capable and their +// projected text is covered by the aggregate. Resource membership is identical: +// no apiVersion, kind, namespace, or name line moves in any root, and the +// validator reported no per-resource mismatch, no missing resource, and no +// duplicate — only this aggregate fingerprint. (The accompanying +// unresolved-substitution notes are the diagnostics described above, emitted +// alongside any aggregate mismatch; they are unchanged and not findings.) +// +// The change is a reduction in what may be deployed. A floating `>=1.0.0` +// range lets ANY newer tag pushed to that registry path be selected and +// reconciled automatically, so an actor able to publish one tag chooses the +// manifests; a fixed tag removes that selection entirely. No identity, +// binding, ServiceAccount, verb, policy, or URL changes, and nothing granted +// to the aws/aws service account this validator protects is touched. +// +// The fingerprint was read from the required job's own output on the approved +// renderer, because the local toolchain is refused as unapproved. It was +// measured after updating the branch onto exact current main (behind_by 0), so +// it describes the merge result rather than a stale base. +const expectedRenderedSurfaceSHA = "a4f9f4f0b9256a9f72159d8c22667622439df6b56b673448220834a53708f296" // authorizationOverlayPaths lists every independently reconciled production // layer where an object can grant privileges to the aws/aws service account. From e30ac82d38dd65dc2b7acb26694a22e59f88b36b Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Sun, 16 Aug 2026 22:39:56 +0200 Subject: [PATCH 3/4] fix(apps): approve the rendered surface for the corrected tenant pins --- scripts/validate-eks-ci-role-policy/main.go | 35 ++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/scripts/validate-eks-ci-role-policy/main.go b/scripts/validate-eks-ci-role-policy/main.go index 2882cf5f4..70d6aa4d4 100644 --- a/scripts/validate-eks-ci-role-policy/main.go +++ b/scripts/validate-eks-ci-role-policy/main.go @@ -587,7 +587,40 @@ const ( // main cdababde. The persistence annotations introduced by #3168 remain in // every surviving selected object; #2741 removes only the already-protected // Headlamp PVC identity and retains the authorization-neutral changes above. -const expectedRenderedSurfaceSHA = "6e6753583bbffa59ce236412f63f27e3d77d03739742ef0a3a34596eb96c5f2a" +// +// Measured for #2737 by the required job's own approved renderer on the merge +// result of head 665a4d38 with exact current main, so it describes what would +// land rather than a stale base. The local toolchain is refused as unapproved +// (kubectl v1.36.1 against the approved v1.36.2), which is why this value comes +// from CI rather than a workstation. +// +// The complete delta is TWO files, one line each, and nothing else: +// +// source.toolkit.fluxcd.io/v1 OCIRepository ascoachingogvaner/ascoachingogvaner +// spec.ref.semver: ">=1.0.0" (removed) +// spec.ref.tag: 1.13.4 (added) +// +// source.toolkit.fluxcd.io/v1 OCIRepository wedding-app/wedding-app +// spec.ref.semver: ">=1.0.0" (removed) +// spec.ref.tag: 1.15.10 (added) +// +// Both are Flux source resources, so they are authorization-capable and their +// projected text is covered by the aggregate. Resource membership is identical: +// no apiVersion, kind, namespace, or name line moves in any root, and the +// validator reported no per-resource mismatch, no missing resource, and no +// duplicate — only this aggregate fingerprint. The accompanying +// unresolved-substitution notes are the diagnostics emitted alongside any +// aggregate mismatch; they are unchanged and are not findings. +// +// The change is a reduction in what may be deployed: a floating `>=1.0.0` range +// lets ANY newer tag pushed to that registry path be selected and reconciled +// automatically, so an actor able to publish one tag chooses the manifests; a +// fixed tag removes that selection. Each tag is the revision production is +// already reconciling (verified read-only against admin@prod), so this pins +// what is running rather than moving it. No identity, binding, ServiceAccount, +// verb, policy, or URL changes, and nothing granted to the aws/aws service +// account this validator protects is touched. +const expectedRenderedSurfaceSHA = "96872df84d578d6397ef1bbdc175f6ccedcc1b1150f5b045deba709407eec610" // authorizationOverlayPaths lists every independently reconciled production // layer where an object can grant privileges to the aws/aws service account. From 977478bd78a72c76c2a4da28da740955936fd954 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Tue, 18 Aug 2026 02:15:07 +0200 Subject: [PATCH 4/4] fix(apps): re-approve authorization fingerprint after levelling to main --- scripts/validate-eks-ci-role-policy/main.go | 46 ++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/scripts/validate-eks-ci-role-policy/main.go b/scripts/validate-eks-ci-role-policy/main.go index 2cf5d2084..6ca87f972 100644 --- a/scripts/validate-eks-ci-role-policy/main.go +++ b/scripts/validate-eks-ci-role-policy/main.go @@ -1008,7 +1008,51 @@ const ( // approved CI toolchain, via the required job. The local kubectl is v1.36.1 // against an approved v1.36.2, so validateRendererVersion fails closed and cannot // corroborate. -const expectedRenderedSurfaceSHA = "ed2767037a88348b22ec8ecfcc8b2081e86b7979dfe3c86d554034980af01fdf" +// Re-measured for #2737 after merging exact main c4fb7f2d, which had advanced +// eleven commits past the base the branch's earlier value was rendered against. +// That stale value never described this merge result, so it is replaced rather +// than re-approved. +// +// The complete delta over main is TWO files, one line each, and nothing else: +// +// source.toolkit.fluxcd.io/v1 OCIRepository ascoachingogvaner/ascoachingogvaner +// spec.ref.semver: ">=1.0.0" (removed) +// spec.ref.tag: 1.13.4 (added) +// +// source.toolkit.fluxcd.io/v1 OCIRepository wedding-app/wedding-app +// spec.ref.semver: ">=1.0.0" (removed) +// spec.ref.tag: 1.15.10 (added) +// +// Both are Flux sources and isAuthorizationKind selects OCIRepository, so their +// projected text is covered by the aggregate. Neither carries a pinned entry in +// expectedResourceSHAs, so the aggregate is the ONLY control that can move for +// this change: a per-identity mismatch was never an available signal here, and +// its absence is therefore not evidence on its own. +// +// Conservation reported by the required job on this merge result: ZERO +// per-identity mismatches, ZERO missing resources and ZERO duplicates, so +// surface membership is unchanged. The 35 unresolved-substitution notes are the +// diagnostics emitted alongside any aggregate mismatch and are not findings; no +// note names either tenant OCIRepository, which is the positive signal that the +// pins did not disturb substitution. +// +// The change is a reduction in what may be deployed: a floating ">=1.0.0" range +// lets ANY newer tag published to that registry path be selected and reconciled +// unattended, so whoever can publish a tag chooses the manifests; a fixed tag +// removes that selection. Each tag is the revision production is already +// reconciling, so this pins what is running rather than moving it. No identity, +// binding, ServiceAccount, verb, policy or URL changes, and nothing granted to +// the aws/aws service account this validator protects is touched. +// +// Main's own approved digest is recorded here in full, so replacing the constant +// does not lose it: +// +// ed2767037a88348b22ec8ecfcc8b2081e86b7979dfe3c86d554034980af01fdf +// +// Only ONE renderer stands behind the new value: the approved CI toolchain via +// the required job. The local kubectl is v1.36.1 against an approved v1.36.2, so +// validateRendererVersion fails closed and cannot corroborate. +const expectedRenderedSurfaceSHA = "21195b64582f0cc99b42cc6ee61c77610972c12b1556c3b254f68b15ce95d7fa" // authorizationOverlayPaths lists every independently reconciled production // layer where an object can grant privileges to the aws/aws service account.