# Catalyst Blueprint umbrella metadata — the upstream chart is resolved as
# a Helm subchart via Chart.yaml `dependencies:`. Catalyst-curated values
# under the `kyverno:` key flow into the upstream subchart unchanged.
#
# Per docs/INVIOLABLE-PRINCIPLES.md #4 (never hardcode), every operationally-
# meaningful value is configurable; cluster overlays in clusters/<sovereign>/
# may override any of these without rebuilding the Blueprint OCI artifact.

global:
  # When set, ALL image pulls in this chart route through this registry.
  # Used post-handover when the Sovereign's own Harbor takes over the
  # proxy_cache role from contabo's central Harbor. Empty = no rewrite
  # (image references use upstream defaults). The upstream Kyverno chart
  # exposes per-controller `kyverno.<controller>.image.registry` knobs.
  # Per-Sovereign overlays wire those alongside this value. Tracked under #560.
  imageRegistry: ""

catalystBlueprint:
  upstream:
    chart: kyverno
    version: "3.8.0"
    repo: "https://kyverno.github.io/kyverno/"

# ─── Upstream chart values (subchart key: kyverno) ───────────────────────
kyverno:
  # CRDs — installed by the umbrella so HelmRelease ordering works (CRDs
  # land before the controller deployments). Default upstream behavior.
  crds:
    install: true

  # HA mode — Kyverno 1.18 splits into 4 controllers. Solo-Sovereign default
  # is replicas=1 per controller; per-Sovereign overlays bump to 3 for true
  # HA when a regional Sovereign needs admission redundancy.
  admissionController:
    replicas: 1
    image:
      registry: ghcr.io
      repository: kyverno/kyverno
      tag: "v1.18.0"
      pullPolicy: IfNotPresent
    resources:
      requests:
        cpu: 100m
        memory: 256Mi
      limits:
        cpu: 1
        memory: 512Mi
    serviceMonitor:
      enabled: false

  backgroundController:
    replicas: 1
    image:
      registry: ghcr.io
      repository: kyverno/background-controller
      tag: "v1.18.0"
      pullPolicy: IfNotPresent
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 256Mi
    serviceMonitor:
      enabled: false

  cleanupController:
    enabled: true
    replicas: 1
    image:
      registry: ghcr.io
      repository: kyverno/cleanup-controller
      tag: "v1.18.0"
      pullPolicy: IfNotPresent
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 256Mi
    serviceMonitor:
      enabled: false

  reportsController:
    replicas: 1
    image:
      registry: ghcr.io
      repository: kyverno/reports-controller
      tag: "v1.18.0"
      pullPolicy: IfNotPresent
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 256Mi
    serviceMonitor:
      enabled: false

  # Reports server — bundled subchart, default disabled. Per-Sovereign
  # overlays enable when scaling out PolicyReport storage.
  reportsServer:
    enabled: false

  # Grafana subchart bundled by upstream — DEFAULT FALSE per
  # docs/BLUEPRINT-AUTHORING.md §11.2 (Catalyst provides bp-grafana
  # separately).
  grafana:
    enabled: false

  # Webhook configuration — upstream defaults apply (namespaceSelector
  # excludes `kube-system`). Per-Sovereign overlays MAY override
  # `config.webhooks.namespaceSelector` and per-controller `failurePolicy`
  # via the upstream chart's controller-scoped settings once 3-replica HA
  # is in place. See upstream `values.yaml` `config:` block for shape.

  # OpenReports CRDs — both flags must agree per upstream schema. Default
  # disabled (matches upstream); per-Sovereign overlays enable BOTH together
  # once the OpenReports CRDs are required.
  openreports:
    enabled: false
    installCrds: false

# ─── Catalyst overlay values (consumed by templates/ in this chart) ──────
kyvernoOverlay:
  networkPolicy:
    enabled: false
  # Default policy bundle — empty; per-Sovereign overlays SET to
  # `pod-security`, `best-practices`, etc. once the policy library lands.
  policyBundle: ""

  # Label-vocabulary enforcement policies (slices E1+E2 of #1095). Two
  # ClusterPolicies that together implement the contract in
  # docs/EPICS-1-6-unified-design.md §1 (label vocab is the join key
  # across compliance, RBAC, billing, networking).
  labelVocab:
    # E1 — mutate-add-openova-labels
    # Mutating ClusterPolicy that, at admission, derives missing
    # openova.io/{org,environment,application,blueprint,vcluster,host-cluster,
    # sovereign} labels from the resource's namespace + ownerReferences and
    # adds them. Default OFF — operator opts in once Organization (slice
    # B1) + Environment (slice B2) CRs exist on the cluster, otherwise
    # the derivation has nothing to read from.
    mutate:
      enabled: false

    # E2 — validate-require-openova-labels
    # Validating ClusterPolicy that REJECTS resources missing the required
    # openova.io/* labels (permissive Audit by default; per-Environment
    # overlay flips to Enforce via EnvironmentPolicy in EPIC-1 #1096).
    # Default OFF — turn on after slice C1/C4 controllers populate labels
    # so existing Sovereign control-plane resources don't trip on it.
    validate:
      enabled: false
      # Audit | Enforce — permissive vs blocking. EnvironmentPolicy.spec.modes
      # drives this per-environment in EPIC-1.
      action: Audit
      # Resource kinds the policy gates. Limited to workload kinds so
      # control-plane Secrets / ConfigMaps don't trip on missing org labels.
      resourceKinds:
        - Deployment
        - StatefulSet
        - DaemonSet
        - Job
        - CronJob
        - Service
        - Ingress
      # Required label keys. Subset of the §1 vocab — only the labels
      # workload-rendering controllers populate. Cluster-scope labels
      # (provider/region/bb/env-type/host-cluster) are set elsewhere.
      requiredLabels:
        - openova.io/organization
        - openova.io/environment
        - openova.io/application
        - openova.io/blueprint
        - openova.io/managed-by
      # Namespaces exempted from the validate rule (control-plane
      # namespaces that pre-date the label vocab — operator extends the
      # set per Sovereign).
      excludeNamespaces:
        - kube-system
        - flux-system
        - cilium
        - cilium-gateway
        - cert-manager
        - openova-system
        - catalyst
        - kyverno
        - monitoring
        - ingress
        - default

# ─── EPIC-1 (#1096) compliance policy library ───────────────────────────
# Slice K (#1096) ships 20 ClusterPolicy template slots; one is deferred
# to slice W2 (hubble-flows-seen — a Go evaluator), so 19 will render at
# most. Every policy is default-OFF; per-Sovereign overlay opts in.
#
# Schema per policy:
#   <name>:
#     enabled: bool                      # required — gate
#     action: "Audit" | "Enforce"        # default Audit; flipped per-Environment
#                                        # by EnvironmentPolicy.spec.compliance.modes
#                                        # (slice C2 controller, future)
#     excludeNamespaces: [string]        # control-plane ns exemption list
#     <policy-specific knobs>            # e.g. allowedRegistryRegex
#
# Default action is `Audit` for every policy (permissive mode). Per
# docs/EPICS-1-6-unified-design.md §4.3 some policies have an
# "enforcing" default mode — those defaults are applied by the future
# environment-controller when it materializes a default
# EnvironmentPolicy on every Environment, NOT here. This values file is
# the per-Sovereign baseline; the Environment-level defaults are the
# next layer up.
#
# Per docs/INVIOLABLE-PRINCIPLES.md #4 — every value is overridable.
compliancePolicies:
  # K1 baseline policies
  multiReplica:
    enabled: false
    action: Audit
    excludeNamespaces: &complianceDefaultExcludes
      - kube-system
      - flux-system
      - cilium
      - cilium-gateway
      - cert-manager
      - openova-system
      - catalyst
      - kyverno
      - monitoring
      - ingress

  pdb:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  topologySpread:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  probesPresent:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  resourceRequests:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  resourceLimits:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  pvcExpansion:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  hpaEffective:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  ciliumL7Mtls:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  fluxManaged:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  harborProxyPull:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes
    # Operator overrides per-Sovereign (e.g.
    # "^harbor\\.omantel\\.openova\\.io/proxy-(ghcr|dockerhub|quay)/.*").
    # The default below allows any host of the form
    # `harbor.<sovereign-domain>/proxy-<upstream>/*`. Operator narrows
    # this per Sovereign overlay. Empty pattern would match everything,
    # which would silently disable the rule.
    allowedRegistryRegex: "^harbor\\..+/proxy-(ghcr|dockerhub|quay|registry-1\\.docker\\.io)/.*"

  imageTagPinned:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  prometheusScrape:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  # K2 added policies
  networkpolicyPresent:
    enabled: false
    action: Audit
    # Match on Namespace kind — `excludeNamespaces` here is consumed via
    # `resources.names` (the namespace IS the resource). Same default
    # exemption set as the workload policies.
    excludeNamespaces: *complianceDefaultExcludes

  otelInjected:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  hubbleFlowsSeen:
    # DEFERRED — see template stub for K2 #16. The Kyverno gate is a
    # no-op; W2 evaluator does the actual check. Setting enabled=true
    # today is harmless (renders nothing) but reserved as the cutover
    # knob once W2 lands so operators can toggle a single flag.
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  runAsNonRootReadonlyRootFs:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  cosignVerified:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes
    # Cosign verifyImages rule fields. Defaults reference openova-io
    # images only; operator extends per Sovereign.
    imageReferences:
      - "ghcr.io/openova-io/*"
    # Cosign public key (PEM). Empty default means the rule emits an
    # invalid policy until operator supplies a real key — surfaces the
    # config gap rather than silently passing. Per
    # docs/INVIOLABLE-PRINCIPLES.md #4 this is operator-configurable,
    # NOT hardcoded.
    publicKey: ""
    rekorURL: "https://rekor.sigstore.dev"

  secretNotInEnv:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes

  backupConfigured:
    enabled: false
    action: Audit
    excludeNamespaces: *complianceDefaultExcludes
