Repository navigation
Description
🤖 Generated by the Agentic Engineer
Evidence
- Migrate the tenant and organisation validation ClusterPolicies to ValidatingPolicy #4995 needs all twelve tenant and organisation validation policies to be
ValidatingPolicyobjects before Kyverno 1.20 removesClusterPolicy(Migrate Kyverno ClusterPolicy and Policy before Kyverno 1.20 removes them #4984). As of 2026-11-03, 8 of 12 are migrated or queued (refactor(policy): move the GitHub team management guard to ValidatingPolicy #5756).restrict-tenant-network-policiesis parked on Let tenant FQDN egress resolve through the platform DNS floor instead of tenant kube-system rules #5823 (refactor(policy): move the tenant network guard to ValidatingPolicy #5759), and the public listener guard is tracked in Preserve the public listener guard while migrating its validation API #5464. restrict-arc-retirement(k8s/bases/infrastructure/cluster-policies/best-practices/restrict-arc-retirement.yaml) has no tracking issue. Its current behaviour is already pinned:scripts/tests/test-arc-retirement-fence.shevaluates about 75 engine cases throughapiCallResponses(real Namespace annotations, including empty, malformed, 403/404/500 lookups, every phase, the baseline and maximum-1 paths and UID binding), and test(kyverno): pin the ARC listener and retirement policies before their ValidatingPolicy rewrite #5031 added thetests/restrict-arc-retirement-*fixtures. Migrate the tenant and organisation validation ClusterPolicies to ValidatingPolicy #4995 still lists it as untested; that line predates both.- It is the only
ClusterPolicyincluster-policies/that reads live state through anapiCallcontext: six of its eight rules read thearc-runnersNamespace'splatform.devantler.tech/arc-retirementannotation, then decides with a long JMESPath condition. Those six arefence-pool-retirement,fence-scale-set-retirement,fence-listener-retirement,fence-retired-listener-pod,fence-credential-recreationandfence-retired-secret; two more,preserve-retirement-journalandpreserve-retiring-namespace, guard the annotation itself on Namespace UPDATE and DELETE. ItswebhookConfiguration.failurePolicyisFail, and the failure action isEnforcewithallowExistingViolations: false. - ARC is still deployed (
k8s/bases/infrastructure/actions-runners/), and the retirement tooling that writes the annotation (scripts/retire-arc-pool.sh,scripts/retire-arc-pool/) is live. The fence must therefore keep the same behaviour; it cannot simply be dropped.
Audience and problem
Whoever retires or recovers the ARC runner pool. The fence is what stops a Flux reconcile or a manual apply from recreating the release, or reopening runner admission, while a retirement is in progress. A migration that changes its decision even in one phase either blocks a legitimate recovery step or lets a retired pool come back. The existing cases feed the Namespace through a JMESPath apiCall context. A ValidatingPolicy reads it through CEL resource.Get instead, so the harness must give the new kind the same Namespace responses, or the old expectations prove nothing about it.
Hypothesis
If the existing engine cases run unchanged in their expected results against a ValidatingPolicy that reads the Namespace through CEL resource.Get, with the same Namespace responses supplied to it, then any decision the rewrite changes shows up as a failing case before deploy, not as a blocked recovery.
Success signal
scripts/tests/test-arc-retirement-fence.shand the test(kyverno): pin the ARC listener and retirement policies before their ValidatingPolicy rewrite #5031 fixtures pass against the new kind with unchanged expected results, and a deliberate mutation of the new policy turns at least one case red (the harness is not vacuous for the new kind).- The
ValidatingPolicypasses the same test unchanged in its expected results, keepsDeny, the same match scope andfailurePolicy: Fail, and replaces theClusterPolicyin the same PR. - After deploy, a read-only check shows the new policy ready and no
ClusterPolicyof that name.
Guardrail: an unreadable Namespace must still deny (fail closed), as it does today through failurePolicy: Fail.
Smallest useful change
- Spike: confirm how the pinned Kyverno CLI (1.19.2) supplies a Namespace to a
ValidatingPolicy'sresource.Get(theapiCallResponsesmechanism, or another context input), and howrequest.oldObjectand user groups reach it. Record the answer here. - Migration PR: the
ValidatingPolicyand deletion of theClusterPolicy, with the same tests pointed at the new kind.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Projects
- StatusShow more project fields📥 Backlog
Activity