Files
cozystack/packages/system
Andrei Kvapil 02c6942adc fix(kubeovn-webhook): restrict the webhook port to the API server (#3955)
## What this PR does

Closes the exposure behind GHSA-g883-q79m-8225 by constraining who can
reach the kube-ovn webhook's serving port. The `/mutate-pods` handler
returns namespace-derived annotations to any caller that reaches it, and
until now nothing stopped an arbitrary in-cluster pod from being that
caller.

### Why the client-certificate path does not close it

cozystack/cozystack#2698 added `--client-ca-file`, deliberately off by
default, as observation mode. Turning it on requires the API server to
**present** a certificate, which it does only when its
`AdmissionConfiguration` names a `kubeConfigFile` for the webhook
plugins.

Checked against a running Cozystack control plane rather than assumed:
the `AdmissionConfiguration` there carries a `PodSecurity` plugin block
and nothing else, so no client certificate is offered to admission
webhooks at all. Flipping to `RequireAndVerifyClientCert` on such a
cluster would reject the API server itself, and with `failurePolicy:
Fail` that stops pod creation cluster-wide.

This matters for how the remaining work was scoped: the plan had been to
observe issuer logs for a day and then pin a CA. No amount of
observation changes the outcome, because the absence is a property of
the control plane's configuration, not of the traffic. Making
`--client-ca-file` usable is a separate, larger change to how the
platform configures the API server, and it is not a prerequisite for
closing the exposure.

### What the policy does

Denies pod traffic and world traffic to the serving port, and needs no
carve-out for the legitimate caller: the API server runs on the host
network, so it is not a Cilium endpoint and `fromEndpoints` never
matches it. Unlike the ingress-nginx admission webhook this component
exists only on the management cluster, so there is no
konnectivity-tunnelled caller to exempt either — and consequently no
forgeable pod label anywhere in the selector.

It is a `CiliumNetworkPolicy` rather than a core `NetworkPolicy`, and
that distinction is the reason it works at all:
`packages/system/kubeovn/values.yaml` sets `ENABLE_NP: false`, so
kube-ovn programs no ACLs and a core NetworkPolicy would be created and
never enforced. The values comment that claimed NetworkPolicy was simply
not an option is corrected — it was true only of the core kind.
`webhookPolicy.enabled` lets a cluster whose networking variant ships no
Cilium turn the object off.

Deny-only with default-deny explicitly disabled, matching the
ingress-nginx admission policy: putting these pods behind a default-deny
would mean enumerating every port they serve and breaking traffic on the
first one forgotten.

### Verification

Eight helm-unittest cases cover the port, the all-namespaces span, the
absence of any label-based exemption, the world deny, the disabled
default-deny, the Cilium kind, the selector and the off switch. The
rendered object was additionally accepted by a live API server via
`kubectl apply --dry-run=server`, so the CRD validates it as written.

Not verified: that a denied pod actually fails to reach the port at
runtime. That needs a live negative test against the policy, which is
the same gap the ingress-nginx admission policy carries.

### Screenshots

Not applicable — no UI change.

### Downstream repositories

Walked the trigger map against the diff. Nothing is reached: the change
is one chart template, its values and its tests under
`packages/system/`, with no package added or removed under
`packages/apps/` or `packages/extra/`, no
`packages/core/platform/values.yaml` key, no platform variant or bundle
change, nothing under `hack/`, and no node prerequisite.

- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:

### Release note

```release-note
fix(kubeovn-webhook): the kube-ovn webhook's serving port is now closed to in-cluster pods and external traffic by a CiliumNetworkPolicy. It previously answered any in-cluster pod with namespace-derived annotations (GHSA-g883-q79m-8225). Disable with webhookPolicy.enabled=false on clusters whose networking variant ships no Cilium.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a Cilium network policy to protect the namespace-annotation
webhook.
* The policy is enabled by default and restricts access to the webhook
port, blocking unauthorized in-cluster and external traffic.
* Standardized the webhook port across its deployment, service, and
network policy configuration.

* **Bug Fixes**
* Improved webhook network isolation when standard Kubernetes
NetworkPolicy enforcement is unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-26 23:04:24 +02:00
..
2026-03-25 15:57:25 +05:00
…