.. SPDX-FileCopyrightText: 2026 Univention GmbH
..
.. SPDX-License-Identifier: AGPL-3.0-only

.. _v1.21.x:

**************
Version 1.21.x
**************

Release notes for Nubus for Kubernetes 1.21.x:

* :ref:`v1.21.0`

.. _v1.21.0:

Version 1.21.0 - 2026-07-20
===========================

This is the thirty-second production release of Nubus for Kubernetes.

.. admonition:: Upgrade path

   For the upgrade to version 1.21.0,
   your deployment must run on version 1.20.x.
   For the general steps to upgrade an existing Nubus for Kubernetes deployment,
   see :external+uv-nubus-kubernetes-operation:ref:`nubus-upgrade`
   in :cite:t:`uv-nubus-kubernetes-operation`.

.. _v1.21.0-changes:

Changes
-------

This section lists the changes in 1.21.0 grouped by component in Nubus for Kubernetes.

.. _v1.21.0-changes-keycloak-service:

Keycloak service
~~~~~~~~~~~~~~~~

* Fix a regression since 1.19.1 where the :program:`Keycloak` LDAP user federation
  re-bound the service account on every operation instead of reusing the pooled
  connection, flooding the *LDAP server* with ``BIND`` requests under load.
  The service account now binds once and reuses the connection.

* Fix Portal and UMC login failing with ``HTTP 401`` after a username is changed in
  case only, for example ``FOO`` to ``foo``.
  :program:`Keycloak` kept serving the cached ``uid`` until its imported-user cache expired.
  The LDAP user federation no longer caches imported users and always reads the ``uid``
  from the *LDAP server*, so a renamed user can sign in immediately.
  The setting is applied immediately on upgrade.

Upgrade Keycloak to version 26.7.0.
This includes fixes for the following security findings:

* :uv:cve:`2026-9796`
* :uv:cve:`2026-9689`
* :uv:cve:`2026-9798`
* :uv:cve:`2026-11986`
* :uv:cve:`2026-9099`
* :uv:cve:`2026-9083`
* :uv:cve:`2026-9086`
* :uv:cve:`2026-9705`
* :uv:cve:`2026-9795`
* :uv:cve:`2026-9799`
* :uv:cve:`2026-9800`
* :uv:cve:`2026-11800`

Neither change requires operator action.

.. _v1.21.0-changes-keycloak-extensions:

Keycloak Extensions
~~~~~~~~~~~~~~~~~~~~

* Align the ``securityContext.enabled`` setting of *Keycloak Extensions* with the
  other Helm charts in Nubus for Kubernetes:

  * :envvar:`nubusKeycloakExtensions.handler.securityContext.enabled`
  * :envvar:`nubusKeycloakExtensions.handler.podSecurityContext.enabled`
  * :envvar:`nubusKeycloakExtensions.proxy.securityContext.enabled`
  * :envvar:`nubusKeycloakExtensions.proxy.podSecurityContext.enabled`

  The ``enabled`` key is now always omitted from the rendered template output.
  Setting it to ``false`` now disables the security context,

.. _v1.21.0-changes-udm-rest-api:

UDM HTTP REST API
~~~~~~~~~~~~~~~~~

* Improve probes of the *UDM HTTP REST API*.
  The liveness and readiness probes now send an HTTP request to the service
  through the probe script ``/usr/local/bin/univention-probe-udm.py``
  shipped in the container image.

  The readiness probe fails when the LDAP server is unreachable,
  so Kubernetes routes traffic away from pods that can't serve requests.
  The liveness probe only fails when the service doesn't answer at all,
  so an LDAP outage doesn't cause pod restarts.

.. _v1.21.0-changes-umc-server:

UMC server
~~~~~~~~~~

* Improve *UMC server* probes, which previously
  only checked that the service port accepts TCP connections.
  The liveness and readiness probes of the *UMC server* container
  now verify that the service answers requests.

* Replace the placeholder probes of the SSSD sidecar container,
  which unconditionally reported success.
  The liveness probe now queries the SSSD NSS responder
  without depending on the LDAP server,
  so a hung responder restarts the container
  while an LDAP outage doesn't.
  The readiness probe verifies the whole lookup path
  from NSS through SSSD to the LDAP server.

* The *UMC gateway* probes now verify that the web server answers requests.

.. _v1.21.0-changes-provisioning-service:

Provisioning Service
~~~~~~~~~~~~~~~~~~~~~

This release fixes an issue where the *Provisioning Service*
could delay the redelivery of an unacknowledged event by up to 30 seconds.
When a consumer received an event but didn't confirm it,
for example because it restarted or was temporarily unavailable,
the event was only redelivered after a long, fixed wait.
Downstream services therefore appeared to receive directory updates with a noticeable delay.
The service now redelivers such events within about one second,
so consumers catch up quickly after a disruption.

This release also improves the durability of queued events.
The message store now flushes events to disk shortly after receiving them,
which reduces the risk of losing events if a node or pod stops unexpectedly.
This durability comes at the cost of a small increase in per-event latency.
The flush interval is configurable through the Helm value
``nubusProvisioning.nats.config.jetstream.fileStore.sync_interval``,
which defaults to ``10ms``.

As part of these changes, the embedded NATS message broker is upgraded to
version 2.14.3.

.. _v1.21.0-changes-portal:

Portal
~~~~~~

* Fix a data exposure on portals that require login,
  where the *Portal* rendered tiles to anonymous visitors
  and included them in the portal data
  before redirecting the visitor to the login page.
  When a portal has the *Users are required to login* option enabled,
  anonymous visitors are now redirected to the login page
  without the *Portal* rendering or serving any categories, tiles, folders,
  or menu entries.
  This affected tiles without a group restriction,
  which are shown to all users and were therefore exposed to anonymous visitors.

.. _v1.21.0-changes-guardian:

Guardian
~~~~~~~~

The *Guardian* component and its container images have been removed
from the Nubus for Kubernetes umbrella chart. This removal is in preparation
for an upcoming change and does not change the behavior of your deployment.
If you set any ``nubusGuardian.*`` values in your custom Helm values, you can
remove them as they no longer have any effect.

.. _v1.21.0-structured-logging:

Structured logging
~~~~~~~~~~~~~~~~~~

Despite prior announcements, structured logging is not yet enabled by default in
Nubus for Kubernetes 1.21. The "old-style" plain logging remains the default.
Nubus for Kubernetes 1.22 changes the default to structured logging.
To keep plain logging in your deployment,
Univention recommends setting all structured-logging configuration options
to ``false``.
Univention will mark "old-style" plain logging as deprecated
and remove it in a future release.
For details,
see :external+uv-nubus-kubernetes-operation:ref:`conf-logging-structured`
in :cite:t:`uv-nubus-kubernetes-operation`.

Included errata updates
-----------------------

The errata updates contain fixes for the following CVEs:

:program:`Authlib`
  * :uv:cve:`2026-41425` (medium)
  * :uv:cve:`2026-41479` (medium)
  * :uv:cve:`2026-44681` (medium)

:program:`Pillow`
  * :uv:cve:`2024-28219` (medium)

:program:`bind9-dnsutils`
  * :uv:cve:`2026-3592` (medium)
  * :uv:cve:`2026-5950` (medium)

:program:`bind9-host`
  * :uv:cve:`2026-3592` (medium)
  * :uv:cve:`2026-5950` (medium)

:program:`bind9-libs`
  * :uv:cve:`2026-3592` (medium)
  * :uv:cve:`2026-5950` (medium)

:program:`brace-expansion`
  * :uv:cve:`2026-33750` (high)
  * :uv:cve:`2026-45149` (high)

:program:`cryptography`
  * :uv:cve:`2026-39892` (critical)

:program:`dulwich`
  * :uv:cve:`2026-47734` (medium)

:program:`github.com/containerd/containerd/v2`
  * :uv:cve:`2026-50195` (critical), :uv:cve:`2026-53492` (critical), :uv:cve:`2026-46680` (high)
  * :uv:cve:`2026-53488` (high), :uv:cve:`2026-47262` (medium), :uv:cve:`2026-53489` (medium)

:program:`go.opentelemetry.io/otel`
  * :uv:cve:`2026-29181` (high)

:program:`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`
  * :uv:cve:`2026-39882` (medium)

:program:`golang.org/x/crypto`
  * :uv:cve:`2026-39830` (critical), :uv:cve:`2026-39831` (critical), :uv:cve:`2026-39832` (critical)
  * :uv:cve:`2026-39833` (critical), :uv:cve:`2026-39834` (critical), :uv:cve:`2026-42508` (critical)
  * :uv:cve:`2026-46595` (critical), :uv:cve:`2026-39829` (high), :uv:cve:`2026-46597` (high)
  * :uv:cve:`2026-39827` (medium), :uv:cve:`2026-39828` (medium), :uv:cve:`2026-39835` (medium)
  * :uv:cve:`2026-46598` (medium)

:program:`golang.org/x/net`
  * :uv:cve:`2026-39821` (critical), :uv:cve:`2026-33814` (high), :uv:cve:`2026-25680` (medium)
  * :uv:cve:`2026-25681` (medium), :uv:cve:`2026-27136` (medium), :uv:cve:`2026-42502` (medium)
  * :uv:cve:`2026-42506` (medium), :uv:cve:`2026-46600` (unknown)

:program:`golang.org/x/sys`
  * :uv:cve:`2026-39824` (low)

:program:`golang.org/x/text`
  * :uv:cve:`2026-56852` (unknown)

:program:`keycloak-services`
  * :uv:cve:`2026-9793` (high), :uv:cve:`2026-9795` (high), :uv:cve:`2026-9689` (medium)
  * :uv:cve:`2026-9798` (medium)

:program:`libc-ares2`
  * :uv:cve:`2026-33630` (unknown)

:program:`libfreetype6`
  * :uv:cve:`2026-50811` (medium)

:program:`libglib2.0-0`
  * :uv:cve:`2026-1484` (medium), :uv:cve:`2026-1489` (medium), :uv:cve:`2026-0988` (low)
  * :uv:cve:`2026-1485` (low)

:program:`libgnutls30`
  * :uv:cve:`2026-3832` (low)

:program:`libgssapi-krb5-2`
  * :uv:cve:`2026-40355` (high)
  * :uv:cve:`2026-40356` (high)

:program:`libk5crypto3`
  * :uv:cve:`2026-40355` (high)
  * :uv:cve:`2026-40356` (high)

:program:`libkrb5-3`
  * :uv:cve:`2026-40355` (high)
  * :uv:cve:`2026-40356` (high)

:program:`libkrb5support0`
  * :uv:cve:`2026-40355` (high)
  * :uv:cve:`2026-40356` (high)

:program:`libopenjp2-7`
  * :uv:cve:`2026-6192` (low)

:program:`libpq5`
  * :uv:cve:`2026-6472` (medium)
  * :uv:cve:`2026-6474` (medium)
  * :uv:cve:`2026-6478` (medium)

:program:`libssh2-1`
  * :uv:cve:`2026-58051` (medium)

:program:`netty-codec-haproxy`
  * :uv:cve:`2026-44893` (high)
  * :uv:cve:`2026-48059` (high)

:program:`netty-codec-http`
  * :uv:cve:`2026-50020` (medium)

:program:`netty-codec-http2`
  * :uv:cve:`2026-48043` (high)
  * :uv:cve:`2026-47244` (medium)
  * :uv:cve:`2026-50560` (medium)

:program:`netty-handler`
  * :uv:cve:`2026-44249` (high)
  * :uv:cve:`2026-45416` (high)
  * :uv:cve:`2026-50010` (high)

:program:`netty-resolver-dns`
  * :uv:cve:`2026-45674` (critical)
  * :uv:cve:`2026-47691` (critical)
  * :uv:cve:`2026-45673` (medium)

:program:`netty-transport-native-epoll`
  * :uv:cve:`2026-45536` (medium)

:program:`nginx`
  * :uv:cve:`2026-27784` (high), :uv:cve:`2026-40701` (medium), :uv:cve:`2026-42934` (medium)
  * :uv:cve:`2026-28753` (low)

:program:`nginx-common`
  * :uv:cve:`2026-27784` (high), :uv:cve:`2026-40701` (medium), :uv:cve:`2026-42934` (medium)
  * :uv:cve:`2026-28753` (low)

:program:`oras.land/oras-go/v2`
  * :uv:cve:`2026-50151` (high), :uv:cve:`2026-50163` (high), :uv:cve:`2026-50162` (medium)
  * :uv:cve:`2026-48978` (low)

:program:`poetry`
  * :uv:cve:`2026-41140` (high)
  * :uv:cve:`2026-34591` (medium)

:program:`postcss`
  * :uv:cve:`2026-41305` (medium)

:program:`postgresql-client-15`
  * :uv:cve:`2026-6472` (medium)
  * :uv:cve:`2026-6474` (medium)
  * :uv:cve:`2026-6478` (medium)

:program:`pytest`
  * :uv:cve:`2025-71176` (medium)

:program:`python3-m2crypto`
  * :uv:cve:`2009-0127` (medium)

:program:`serialize-javascript`
  * :uv:cve:`2026-34043` (high)

:program:`stdlib`
  * :uv:cve:`2026-32281` (high), :uv:cve:`2026-32283` (high), :uv:cve:`2026-33811` (high)
  * :uv:cve:`2026-33814` (high), :uv:cve:`2026-39820` (high), :uv:cve:`2026-39822` (high)
  * :uv:cve:`2026-39836` (high), :uv:cve:`2026-42499` (high), :uv:cve:`2026-42504` (high)
  * :uv:cve:`2025-61727` (medium), :uv:cve:`2025-61728` (medium), :uv:cve:`2025-61730` (medium)
  * :uv:cve:`2026-27142` (medium), :uv:cve:`2026-27145` (medium), :uv:cve:`2026-32282` (medium)
  * :uv:cve:`2026-32288` (medium), :uv:cve:`2026-32289` (medium), :uv:cve:`2026-39823` (medium)
  * :uv:cve:`2026-39825` (medium), :uv:cve:`2026-39826` (medium), :uv:cve:`2026-42505` (medium)
  * :uv:cve:`2026-42507` (medium), :uv:cve:`2026-27139` (low)

:program:`urllib3`
  * :uv:cve:`2026-44432` (high)

:program:`uuid`
  * :uv:cve:`2026-41907` (high)
