Skip to content

Migrate the tenant and organisation validation ClusterPolicies to ValidatingPolicy #4995

Open
2 of 4 issues completed

Description

@devantler

🤖 Generated by the Agentic Engineer (interactive Claude Code session)

Evidence and problem

Kyverno 1.20 is planned to remove ClusterPolicy (#4984). These 12 validation policies in k8s/bases/infrastructure/cluster-policies/best-practices/ guard tenants, GitHub organisation management and retirements; each must exist as a ValidatingPolicy (policies.kyverno.io) before 1.20 is installed:

audit-privileged-rbac, restrict-arc-openbao-listener, restrict-arc-retirement, restrict-explicit-dns-records, restrict-github-team-external-identity, restrict-github-team-management, restrict-homepage-service-groups, restrict-tenant-issuer-refs, restrict-tenant-network-policies, restrict-tenant-route-hostnames, restrict-tenant-secret-stores, restrict-unifi-management-policies.

Ten of the twelve already have Kyverno CLI tests; restrict-arc-openbao-listener and restrict-arc-retirement have none.

How every migration batch works

  • Test first. Of the 49 ClusterPolicy manifests, 28 are named in no tests/**/kyverno-test.yaml (counted 2026-10-17 by policy name). Before rewriting a policy, add a Kyverno CLI test that pins its current behaviour — at least one resource it must act on and one it must leave alone — and see it pass against the ClusterPolicy. The same test, pointed at the new kind, must pass unchanged in its expected results.
  • Keep the action. Each rewritten policy keeps its failure action as recorded in tests/policy-failure-actions.json (Enforce stays Enforce, Audit stays Audit), its match scope and its exclusions.
  • No gap in enforcement. Add the new policy and delete the ClusterPolicy in the same PR, so Flux applies the replacement before it prunes the old one. Kinds whose two versions could both act on the same request (mutation or generation) say how double application is avoided.
  • Confirm the capability first. For each rule, confirm the replacement kind can express it at Kyverno 1.19.1 (the running version). A rule it cannot express is recorded on Migrate Kyverno ClusterPolicy and Policy before Kyverno 1.20 removes them #4984 and blocks only that policy, not the batch.
  • Validate with kyverno test ./tests and scripts/validate-kyverno-fixture-evaluation.sh (CI's ⚖️ Validate cluster policies step), the layer builds in platform/AGENTS.md, and after deploy a read-only check that each new policy reports ready and the old one is gone.

Acceptance criteria

  • Every policy listed above has a CLI test that passed against the ClusterPolicy before the rewrite.
  • Each is a ValidatingPolicy with the same failure action, scope and exclusions, and the old ClusterPolicy is deleted in the same PR.
  • kyverno test ./tests and the fixture-evaluation check pass in CI.
  • After deploy, each new policy reports ready and no ClusterPolicy of these names remains.

Priority High, Effort High, Service class Risk reduction. These rules keep tenants inside their boundaries; losing them in a 1.20 upgrade would be silent. Effort includes adding the missing tests, the CEL rewrite, review and one production deploy. No prerequisite; #4994 removes the time pressure but is not required first. Part of #4984.

Activity

  1. added theissue type on Oct 17, 2026
  2. moved this to 🫴 Ready in 🌊 Project Boardon Oct 17, 2026
  3. updated Effort High and Priority High on Oct 17, 2026
  4. self-assigned this
    on Oct 17, 2026
  5. devantler commented on Oct 17, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress — test-first step for the two untested policies (platform#5031, merged 2026-10-17 21:18Z)

    • restrict-arc-openbao-listener now has CLI tests: the audited listener passes, the same name outside openbao fails, and extra data, binaryData or a changed listener each fail.
    • restrict-arc-retirement has CLI tests for 5 of its 8 rules: fence-retired-listener-pod, fence-retired-secret, preserve-retiring-namespace, fence-credential-recreation (the update path past baseline) and preserve-retirement-journal. The journal that the policy reads by API call is supplied through values.yaml, per resource.
    • Each pinned rule was broken on purpose, and a fixture failed every time.

    Still to do before this policy's rewrite: fence-pool-retirement, fence-scale-set-retirement and fence-listener-retirement. They compare the request against whole recorded baseline specs, so their fixtures need a full baseline record in values.yaml. The other ten policies already had tests, so the CEL rewrite itself has not started.

  6. removed their assignment
    on Oct 19, 2026
  7. 7 remaining items

  8. added a commit that references this issue on Oct 27, 2026
  9. added 4 commits that reference this issue on Oct 27, 2026
  10. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress: restrict-tenant-issuer-refs is now a ValidatingPolicy in production (3 of 12).

    #5743, #5749, #5751 are in the merge queue and #5756 is in review. Each gets its own line here once it has deployed.

  11. added a commit that references this issue on Nov 2, 2026
  12. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress: restrict-tenant-route-hostnames is now a ValidatingPolicy in production (4 of 12).

    This read checks that the replacement took place. It did not send a live request to the policy; the same-denial evidence is on #5749.

  13. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress: restrict-github-team-external-identity is now a ValidatingPolicy in production (5 of 12).

    #5743, #5756 and #5758 are still queued and are recorded when each one deploys.

  14. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress: audit-privileged-rbac is now a ValidatingPolicy in production (6 of 12).

    #5743 and #5756 are still queued and are recorded when each one deploys.

  15. devantler commented on Nov 2, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress: restrict-homepage-service-groups is now a ValidatingPolicy in production (7 of 12).

    #5756 is still queued and is recorded when it deploys.

  16. devantler commented on Nov 10, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Progress, read from production on 10 November about 17:25Z: 10 of the 12 listed policies are now ValidatingPolicy and their ClusterPolicy is gone.

    • restrict-github-team-management: refactor(policy): move the GitHub team management guard to ValidatingPolicy #5756 merged on 4 November as 33497bde5f96acafee329785aef421c5de7f3c89. Its ValidatingPolicy reports ready, and no ClusterPolicy of that name remains. This was not recorded here when it deployed.
    • restrict-unifi-management-policies no longer exists under that name. Its rules now live in three ValidatingPolicy objects, restrict-unifi-apply-management-policies, restrict-unifi-observe-only and restrict-unifi-prune-management-policies. All three report ready, and no ClusterPolicy of the old name remains.
    • The other eight already recorded above still report ready, with no ClusterPolicy left.

    Two remain as ClusterPolicy:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

Priority

High

Effort

High

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions