diff --git a/k8s/bases/infrastructure/cluster-policies/best-practices/restrict-doggy-countdown-hostnames.yaml b/k8s/bases/infrastructure/cluster-policies/best-practices/restrict-doggy-countdown-hostnames.yaml new file mode 100644 index 000000000..4db51bc83 --- /dev/null +++ b/k8s/bases/infrastructure/cluster-policies/best-practices/restrict-doggy-countdown-hostnames.yaml @@ -0,0 +1,43 @@ +# The doggy-countdown deployment is sourced from a separately published OCI +# artifact and is applied as a ServiceAccount with permission to manage +# HTTPRoutes in this namespace. Keep that publishing path from claiming another +# hostname on the shared, cross-namespace Gateway (and from making external-dns +# publish that claim). Requiring exactly one hostname also rejects a hostname- +# less route, which Gateway API would otherwise match against every hostname. +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: restrict-doggy-countdown-hostnames + annotations: + policies.kyverno.io/title: Restrict Doggy Countdown Hostnames + policies.kyverno.io/category: Security, Gateway API + policies.kyverno.io/severity: high + policies.kyverno.io/subject: HTTPRoute + policies.kyverno.io/minversion: 1.6.0 + policies.kyverno.io/description: >- + Restricts HTTPRoutes in the doggy-countdown namespace to the tenant's + assigned simba hostname so its remote manifest source cannot claim other + names on the shared platform Gateway. +spec: + validationFailureAction: Enforce + background: true + rules: + - name: require-doggy-countdown-hostname + match: + any: + - resources: + kinds: + - HTTPRoute + namespaces: + - doggy-countdown + validate: + message: >- + Doggy countdown HTTPRoutes must declare exactly one hostname: + simba.${domain}. + deny: + conditions: + any: + - key: "{{ request.object.spec.hostnames || `[]` }}" + operator: NotEquals + value: + - "simba.${domain}" diff --git a/k8s/bases/infrastructure/cluster-policies/kustomization.yaml b/k8s/bases/infrastructure/cluster-policies/kustomization.yaml index 381a7b082..ed7580fe6 100644 --- a/k8s/bases/infrastructure/cluster-policies/kustomization.yaml +++ b/k8s/bases/infrastructure/cluster-policies/kustomization.yaml @@ -12,6 +12,7 @@ resources: - best-practices/disable-default-sa-automount.yaml - best-practices/disallow-latest-tag.yaml - best-practices/propagate-reloader-to-flagger-primary.yaml + - best-practices/restrict-doggy-countdown-hostnames.yaml - best-practices/restrict-tenant-secret-stores.yaml - best-practices/validate-host-restrictions.yaml - best-practices/validate-pdb-drain-safe.yaml diff --git a/tests/restrict-doggy-countdown-hostnames/kyverno-test.yaml b/tests/restrict-doggy-countdown-hostnames/kyverno-test.yaml new file mode 100644 index 000000000..c395bad7b --- /dev/null +++ b/tests/restrict-doggy-countdown-hostnames/kyverno-test.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: restrict-doggy-countdown-hostnames +policies: + - >- + ../../k8s/bases/infrastructure/cluster-policies/best-practices/restrict-doggy-countdown-hostnames.yaml +resources: + - resources.yaml +results: + - policy: restrict-doggy-countdown-hostnames + rule: require-doggy-countdown-hostname + resources: + - doggy-countdown/intended-hostname + kind: HTTPRoute + result: pass + - policy: restrict-doggy-countdown-hostnames + rule: require-doggy-countdown-hostname + resources: + - doggy-countdown/arbitrary-hostname + - doggy-countdown/hostname-less + - doggy-countdown/mixed-hostnames + kind: HTTPRoute + result: fail + - policy: restrict-doggy-countdown-hostnames + rule: require-doggy-countdown-hostname + resources: + - another-tenant/arbitrary-hostname + kind: HTTPRoute + result: skip diff --git a/tests/restrict-doggy-countdown-hostnames/resources.yaml b/tests/restrict-doggy-countdown-hostnames/resources.yaml new file mode 100644 index 000000000..44f35d107 --- /dev/null +++ b/tests/restrict-doggy-countdown-hostnames/resources.yaml @@ -0,0 +1,44 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: intended-hostname + namespace: doggy-countdown +spec: + hostnames: + - "simba.${domain}" +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: arbitrary-hostname + namespace: doggy-countdown +spec: + hostnames: + - login.platform.devantler.tech +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: hostname-less + namespace: doggy-countdown +spec: {} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: mixed-hostnames + namespace: doggy-countdown +spec: + hostnames: + - "simba.${domain}" + - login.platform.devantler.tech +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: arbitrary-hostname + namespace: another-tenant +spec: + hostnames: + - login.platform.devantler.tech