apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: enforce-api-ingress-security
  annotations:
    policies.kyverno.io/title: Enforce TLS and mTLS guardrails for edge APIs
    policies.kyverno.io/category: API Governance
    policies.kyverno.io/severity: medium
spec:
  validationFailureAction: enforce
  background: true
  failurePolicy: Fail
  rules:
    - name: require-nginx-tls-version
      match:
        any:
          - resources:
              kinds: [Ingress]
      preconditions:
        all:
          - key: "{{ request.object.metadata.annotations['kubernetes.io/ingress.class'] || '' }}"
            operator: Equals
            value: nginx
      validate:
        message: "Public ingress endpoints must restrict TLS protocols to 1.2 and 1.3"
        pattern:
          metadata:
            annotations:
              nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
    - name: require-mtls-authentication
      match:
        any:
          - resources:
              kinds: [Ingress]
      preconditions:
        all:
          - key: "{{ request.object.metadata.annotations['kubernetes.io/ingress.class'] || '' }}"
            operator: Equals
            value: nginx
      validate:
        message: "Mutual TLS is required for partner API ingress"
        pattern:
          metadata:
            annotations:
              nginx.ingress.kubernetes.io/auth-tls-secret: "platform/edge-mtls"
              nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
    - name: block-privileged-backends
      match:
        any:
          - resources:
              kinds: [HTTPRoute]
              apiGroups: [gateway.networking.k8s.io]
      validate:
        message: "HTTPRoute backends serving APIs must not target privileged namespaces"
        foreach:
          - list: "request.object.spec.rules[].backendRefs[]"
            deny:
              conditions:
                all:
                  - key: "{{ element.namespace || request.namespace }}"
                    operator: AnyIn
                    value: ["kube-system", "istio-system", "cert-manager"]
