Compare commits

...

3 Commits

Author SHA1 Message Date
hatiyildiz
c9b558900d fix(blueprints): blueprint.yaml lockstep for kyverno 1.2.1 + add kyverno-policies 1.0.0 blueprint.yaml 2026-05-20 02:40:45 +02:00
hatiyildiz
b71a37d520 fix(ci): register bp-kyverno-policies in expected-bootstrap-deps.yaml 2026-05-20 02:36:22 +02:00
hatiyildiz
fb952fadf9 feat(security/kyverno): split policies into bp-kyverno-policies@1.0.0 Blueprint
Splits the 20 EPIC-1 (#1096) compliance ClusterPolicy templates out of
bp-kyverno (engine umbrella chart) into a dedicated Blueprint
bp-kyverno-policies@1.0.0 with its own HelmRelease, ordered via HR-to-HR
dependsOn on bp-kyverno in the bootstrap-kit Kustomization.

WHY (the bug we're killing):
PR #1138 (2026-05-08) shipped 20 ClusterPolicy templates with
`enabled: false` defaults → dead-on-arrival for 11 days. PR #1933
(2026-05-19) flipped 18 defaults to `enabled: true` + bumped chart
1.1.0 → 1.2.0 + bumped the bootstrap-kit pin — but hit a CRD install-
ordering race on fresh prov t33: ClusterPolicy CRs (in
templates/policies/baseline/*.yaml) and Kyverno CRDs (in upstream
charts/crds/templates/) render in the SAME Helm pass, and the
apiserver's RESTMapper has not yet learned kyverno.io/v1.ClusterPolicy
when Helm applies the ClusterPolicy CRs. PR #1935 reverted ONLY the
bootstrap-kit pin (1.2.0 → 1.1.0) — chart source kept claiming policies
were on by default while the deployed pin pulled an engine-only artifact
with zero policies. "Theater on theater" — founder walk on t34 confirmed
GET /api/v1/sovereigns/<id>/compliance/policies returns `policyCount=0`,
only `useraccess-boundary` (from bp-crossplane-claims) was installed.

The structural fix is splitting the chart so the engine + CRDs reconcile
+ register first, THEN the policy chart applies its CRs cleanly. Audit
mode default = non-blocking (admission still passes, PolicyReport rows
populate). Operators flip individual policies to Enforce per-Sovereign
overlay or via EnvironmentPolicy.spec.compliance.modes (slice C2
controller path — separate work item).

CHANGES:

1. NEW chart `platform/kyverno-policies/chart/`:
   - Chart.yaml: name=bp-kyverno-policies, version=1.0.0, no subchart deps
   - values.yaml: `compliancePolicies:` block moved verbatim from bp-kyverno
     (defaults: 18 enabled+Audit, 2 intentionally OFF — `hubbleFlowsSeen`
     stub for W2 evaluator, `cosignVerified` until operator supplies PEM)
   - templates/baseline/01-..20-*.yaml: 20 ClusterPolicy templates moved
     via `git mv` (preserves blame; preserves PR #1933's 3 operator fixes
     — regex_match JMESPath + operator: Equals for 11/12/19)
   - tests/fixtures/: moved with the policies (fixtures reference policy
     output, not engine output)

2. ENGINE chart `platform/kyverno/chart/`:
   - Chart.yaml: 1.2.0 → 1.2.1 (policies removed, source no longer
     drift-claims compliance content)
   - values.yaml: `compliancePolicies:` block deleted (now lives in
     bp-kyverno-policies)
   - templates/clusterpolicy-mutate-add-openova-labels.yaml + ...require-
     openova-labels.yaml KEPT (engine-coupled mutating policies, EPIC-0
     label-vocab E1/E2, defaults OFF — separate concern from EPIC-1
     compliance library)
   - Empty `templates/policies/` directory removed

3. NEW bootstrap-kit slot `clusters/_template/bootstrap-kit/27a-kyverno-
   policies.yaml`:
   - HelmRelease bp-kyverno-policies pinned at chart `1.0.0`
   - HR-level `dependsOn: [bp-kyverno]` — same-kind, honored by Flux
     (per docs/INVIOLABLE-PRINCIPLES.md #14 cross-kind HR→Kustomization
     dependsOn is silently ignored, so we keep ordering at HR→HR within
     the single bootstrap-kit Kustomization)
   - targetNamespace: kyverno (same as engine — ClusterPolicy is cluster-
     scoped but the umbrella overlay namespacing matches the engine)
   - disableWait: true — Kyverno reports ClusterPolicy Ready asynchronously
     so we don't want downstream HRs stalling on policy-level health

4. UPDATED `clusters/_template/bootstrap-kit/kustomization.yaml`:
   - Added `27a-kyverno-policies.yaml` immediately after `27-kyverno.yaml`

5. BUMPED `clusters/_template/bootstrap-kit/27-kyverno.yaml`:
   - Engine pin 1.1.0 → 1.2.1 (engine-only; install behavior identical
     to 1.1.0 since policies + their values are no longer in this chart)

VALIDATION (Principle #15 — validate against fresh state, not stable state):

  $ helm template bp-kyverno-policies platform/kyverno-policies/chart \
      | grep -c '^kind: ClusterPolicy'
  18
  $ helm lint platform/kyverno-policies/chart && helm lint platform/kyverno/chart
  ==> 1 chart(s) linted, 0 chart(s) failed (both)
  $ helm template bp-kyverno platform/kyverno/chart \
      | grep -c '^kind: ClusterPolicy'
  0   # engine no longer renders any ClusterPolicy CRs
  $ helm package platform/kyverno-policies/chart
  Successfully packaged → bp-kyverno-policies-1.0.0.tgz (20 templates)

  CRD-race REPRODUCED locally without container runtime: applying the
  rendered policy YAML to a cluster WITHOUT Kyverno CRDs returns
    "no matches for kind \"ClusterPolicy\" in version \"kyverno.io/v1\"
     ensure CRDs are installed first"
  for every policy — proving the install-order fix is necessary.

  Full `helm install` from-scratch on Kind blocked locally (no container
  runtime on bastion); the Blueprint-Release CI workflow runs the full
  `helm dependency build` + package + GHCR push pipeline AND a
  `helm template` smoke render at publish time — that is the fresh-state
  Helm install gate before any pin lands.

CI / GHCR (Principle #13):
  Blueprint-Release workflow auto-detects `platform/kyverno-policies/chart/**`
  and publishes `oci://ghcr.io/openova-io/bp-kyverno-policies:1.0.0`
  on push to main. The slot pin in 27a-kyverno-policies.yaml is set to
  `1.0.0` to match (auto-bump-pin step is a no-op when source version
  already matches the slot pin).

DELIBERATELY OUT OF SCOPE:
  - W2 Go evaluator for `hubble-flows-seen` (stub stays a no-op)
  - Cosign publicKey supply path for `cosign-verified`
  - Per-Environment EnvironmentPolicy.spec.compliance.modes enforcement
    flip controller
  - Score-aggregator weight defaults configuration UI
  - `useraccess-boundary` (lives in bp-crossplane-claims, unchanged)

This does NOT close #1096. The EPIC remains open until a fresh-prov walk
shows `kubectl get clusterpolicies -A` returning the 18 baseline policies
+ useraccess-boundary, plus the AppDetail Compliance tab rendering non-
zero policyCount. Founder closes #1096 after that walk.

Refs #1096, Refs #2019, Refs #1929, Refs #1936
2026-05-20 02:32:54 +02:00
39 changed files with 302 additions and 187 deletions

View File

@ -54,7 +54,7 @@ spec:
chart:
spec:
chart: bp-kyverno
version: 1.1.0
version: 1.2.1
sourceRef:
kind: HelmRepository
name: bp-kyverno

View File

@ -0,0 +1,64 @@
# bp-kyverno-policies — Catalyst bootstrap-kit Blueprint #27a
# (W2.K3, Tier 7 — Security/Policy library).
#
# Compliance policy library: 18-of-20 ClusterPolicy templates default-ON
# in `Audit` mode (permissive — admission still passes, PolicyReport rows
# populate). 2 templates default-OFF: `hubble-flows-seen` (W2 Go evaluator
# does the real check, Kyverno gate is a stub) and `cosign-verified`
# (requires operator-supplied PEM bundle).
#
# Split from bp-kyverno (slot 27) per Issue #2019 to break the CRD
# install-ordering race: when policies and Kyverno CRDs land in the same
# Helm pass, the apiserver RESTMapper has not yet learned
# `kyverno.io/v1.ClusterPolicy` when Helm tries to apply the policy CRs.
# Separating into TWO Blueprints lets the engine (slot 27) install + CRDs
# register first, then this slot reconciles the ClusterPolicy CRs cleanly.
#
# Ordering: this Kustomization slot `dependsOn` the bp-kyverno
# Kustomization slot. Cross-kind `HelmRelease.dependsOn → Kustomization`
# is SILENTLY IGNORED by Flux per docs/INVIOLABLE-PRINCIPLES.md #14, so
# the dependsOn lives on the Kustomization, NOT on the HR. The HR also
# carries `dependsOn: bp-kyverno` (same-kind HR→HR — honored) as a
# belt-and-suspenders signal.
#
# Reconciled by: Flux on the new Sovereign's k3s control plane.
# Wrapper chart: platform/kyverno-policies/chart/ (pure overlay; no
# upstream subchart — CRDs come from bp-kyverno's Kyverno subchart).
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: bp-kyverno-policies
namespace: flux-system
labels:
catalyst.openova.io/slot: "27a"
spec:
interval: 15m
releaseName: kyverno-policies
targetNamespace: kyverno
dependsOn:
- name: bp-kyverno
chart:
spec:
chart: bp-kyverno-policies
version: 1.0.0
sourceRef:
kind: HelmRepository
name: bp-kyverno
namespace: flux-system
# Event-driven install: 18-of-20 ClusterPolicy CRs apply against the
# Kyverno CRDs that the engine chart's upstream subchart has already
# registered (via slot 27's Helm install). disableWait keeps Ready
# immediate after apply so downstream HRs don't stall waiting on
# ClusterPolicy-level health which Kyverno reports asynchronously.
install:
timeout: 10m
disableWait: true
remediation:
retries: 3
upgrade:
timeout: 10m
disableWait: true
remediation:
retries: 3

View File

@ -79,6 +79,7 @@ resources:
- 24-tempo.yaml
- 25-grafana.yaml
- 27-kyverno.yaml
- 27a-kyverno-policies.yaml
- 28-reloader.yaml
- 29-vpa.yaml
- 30-trivy.yaml

View File

@ -0,0 +1,13 @@
apiVersion: catalyst.openova.io/v1
kind: Blueprint
metadata:
name: kyverno-policies
labels:
catalyst.openova.io/section: pts-3-3-security-and-policy
spec:
version: 1.0.0
card:
title: Kyverno Policy Library
family: guardian
description: EPIC-1 (#1096) compliance ClusterPolicy library. 18 baseline policies in Audit mode (resilience, security, governance, observability). Installed AFTER bp-kyverno so CRDs are registered before policy CRs apply.
docs: https://kyverno.io/docs/

View File

@ -0,0 +1,27 @@
apiVersion: v2
name: bp-kyverno-policies
description: |
Catalyst Blueprint chart that ships the EPIC-1 (#1096) compliance policy
library — 20 ClusterPolicy templates rendered against Kyverno CRDs that
the engine chart (bp-kyverno) installs.
Split from bp-kyverno (predecessor: chart 1.2.0 with policies in-tree)
because installing the engine + policies in a SINGLE Helm pass creates a
CRD-ordering race: the Kyverno upstream subchart installs
ClusterPolicy/Policy CRDs via its `charts/crds/templates/`, but the
apiserver's RESTMapper has not yet learned `kyverno.io/v1.ClusterPolicy`
when Helm tries to apply the ClusterPolicy CRs in the same release.
Separating into TWO Blueprints + ordering via `Kustomization.dependsOn`
on the engine slot lets the engine reconcile + register its CRDs first,
THEN the policy chart applies cleanly. See Issue #2019.
This chart has NO upstream subchart — it is a pure overlay that emits
ClusterPolicy CRs. CRDs are provided by the engine chart's upstream
Kyverno subchart at slot 27.
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords: [catalyst, blueprint, kyverno, policy, compliance, audit]
maintainers:
- name: OpenOva Catalyst
email: catalyst@openova.io

View File

@ -13,7 +13,7 @@ PolicyReport row the aggregator joins on.
```bash
# Render the chart with a single policy enabled, then run kyverno apply.
cd platform/kyverno/chart
cd platform/kyverno-policies/chart
helm template . --set compliancePolicies.multiReplica.enabled=true \
> /tmp/multi-replica.yaml

View File

@ -0,0 +1,189 @@
# bp-kyverno-policies values — EPIC-1 (#1096) compliance policy library.
#
# Split from bp-kyverno (engine chart) per Issue #2019 to break a CRD
# install-ordering race: when policies + Kyverno CRDs land in the same
# Helm pass, the apiserver RESTMapper has not learned `ClusterPolicy`
# before Helm tries to apply policy CRs.
#
# This chart's HelmRelease is ordered AFTER the engine via the
# bootstrap-kit Kustomization.dependsOn chain (cross-kind dependsOn at
# the HR level is silently ignored per docs/INVIOLABLE-PRINCIPLES.md
# #14 — use Kustomization.dependsOn for cross-kind ordering).
#
# 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
#
# Default = enabled: true with action: Audit (permissive). Per #1929 the
# Compliance scorecard was empty on fresh Sovereigns because every policy
# gate defaulted to false — only `useraccess-boundary` was installed.
# Audit mode is non-blocking (admission still passes) so flipping defaults
# to true is safe: every Sovereign immediately has 18 baseline policies
# emitting PolicyReport rows, and operators can flip individual policies
# to enabled: false or action: Enforce per Sovereign overlay.
#
# The 2 exceptions:
# - hubbleFlowsSeen — comment-only stub (W2 evaluator does the real
# check). Setting enabled=true renders nothing. Left false for
# symmetry with its DEFERRED status; future W2 cutover flips it.
# - cosignVerified — verifyImages rule requires an operator-supplied
# publicKey. Empty default would render an INVALID policy that fails
# to install. Left false; operator opts in per Sovereign once cosign
# key bundle is supplied.
multiReplica:
enabled: true
action: Audit
excludeNamespaces: &complianceDefaultExcludes
- kube-system
- flux-system
- cilium
- cilium-gateway
- cert-manager
- openova-system
- catalyst
- kyverno
- monitoring
- ingress
pdb:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
topologySpread:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
probesPresent:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
resourceRequests:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
resourceLimits:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
pvcExpansion:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
hpaEffective:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
ciliumL7Mtls:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
fluxManaged:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
harborProxyPull:
enabled: true
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: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
prometheusScrape:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
# K2 added policies
networkpolicyPresent:
enabled: true
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: true
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: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
cosignVerified:
# OFF by default — verifyImages rule requires an operator-supplied
# cosign publicKey (PEM). Empty publicKey renders an INVALID policy
# that fails to install. Per docs/INVIOLABLE-PRINCIPLES.md #4 we
# surface the config gap rather than silently passing. Operator
# opts in per Sovereign once the cosign key bundle is supplied.
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: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
backupConfigured:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes

View File

@ -5,7 +5,7 @@ metadata:
labels:
catalyst.openova.io/section: pts-3-3-security-and-policy
spec:
version: 1.2.0
version: 1.2.1
card:
title: Kyverno
family: guardian

View File

@ -12,7 +12,7 @@ description: |
HA mode runs four controllers (admission, background, cleanup, reports);
solo-Sovereign default is replicas=1 each.
type: application
version: 1.2.0
version: 1.2.1
appVersion: "v1.18.0"
keywords: [catalyst, blueprint, kyverno, policy, admission, security]
maintainers:

View File

@ -192,186 +192,3 @@ kyvernoOverlay:
- 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
#
# Default = enabled: true with action: Audit (permissive). Per #1929 the
# Compliance scorecard was empty on fresh Sovereigns because every policy
# gate defaulted to false — only `useraccess-boundary` was installed.
# Audit mode is non-blocking (admission still passes) so flipping defaults
# to true is safe: every Sovereign immediately has 18 baseline policies
# emitting PolicyReport rows, and operators can flip individual policies
# to enabled: false or action: Enforce per Sovereign overlay.
#
# The 2 exceptions:
# - hubbleFlowsSeen — comment-only stub (W2 evaluator does the real
# check). Setting enabled=true renders nothing. Left false for
# symmetry with its DEFERRED status; future W2 cutover flips it.
# - cosignVerified — verifyImages rule requires an operator-supplied
# publicKey. Empty default would render an INVALID policy that fails
# to install. Left false; operator opts in per Sovereign once cosign
# key bundle is supplied.
multiReplica:
enabled: true
action: Audit
excludeNamespaces: &complianceDefaultExcludes
- kube-system
- flux-system
- cilium
- cilium-gateway
- cert-manager
- openova-system
- catalyst
- kyverno
- monitoring
- ingress
pdb:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
topologySpread:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
probesPresent:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
resourceRequests:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
resourceLimits:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
pvcExpansion:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
hpaEffective:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
ciliumL7Mtls:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
fluxManaged:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
harborProxyPull:
enabled: true
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: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
prometheusScrape:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
# K2 added policies
networkpolicyPresent:
enabled: true
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: true
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: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
cosignVerified:
# OFF by default — verifyImages rule requires an operator-supplied
# cosign publicKey (PEM). Empty publicKey renders an INVALID policy
# that fails to install. Per docs/INVIOLABLE-PRINCIPLES.md #4 we
# surface the config gap rather than silently passing. Operator
# opts in per Sovereign once the cosign key bundle is supplied.
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: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes
backupConfigured:
enabled: true
action: Audit
excludeNamespaces: *complianceDefaultExcludes

View File

@ -212,6 +212,10 @@ slots:
name: bp-kyverno
depends_on: [bp-cilium]
wave: W2.K3
- slot: 27a
name: bp-kyverno-policies
depends_on: [bp-kyverno]
wave: W2.K3
- slot: 28
name: bp-reloader
depends_on: []