.. 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 introduced in 1.19.1
  where the :program:`Keycloak` LDAP user federation
  bound the service account again for every operation
  instead of reusing the pooled connection.
  Under load,
  this flooded the *LDAP server* with ``BIND`` requests.
  The service account now binds once and reuses the connection.

* Fix sign-in failures with ``HTTP 401`` in *Portal* and *UMC*
  after a username changes only in letter case,
  for example from ``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 that a renamed user can sign in immediately.
  The upgrade immediately applies the setting.

* 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`

* These changes don't require operator action.

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

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

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

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

The rendered template output now always omits the ``enabled`` key.
Setting the value to ``false`` deactivates the security context.

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

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

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

The probes now behave as follows:

* 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.
  Previously,
  the probes only checked whether the service port accepted 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
~~~~~~~~~~~~~~~~~~~~~

* Fix an issue where the *Provisioning Service*
  could delay redelivery of an unacknowledged event by up to 30 seconds.
  If a consumer received an event but didn't confirm it,
  for example because it restarted or was temporarily unavailable,
  the service redelivered the event only after a long, fixed wait.
  As a result,
  downstream services could 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.

* Improve the durability of queued events.
  The message store flushes events to disk shortly after receiving them,
  which reduces the risk of losing events if a node or pod stops unexpectedly.
  This change slightly increases per-event latency.
  The flush interval is configurable through the Helm Chart value
  ``nubusProvisioning.nats.config.jetstream.fileStore.sync_interval``,
  which defaults to ``10ms``.

* These changes also upgrade the embedded NATS message broker to version 2.14.3.

.. _v1.21.0-changes-portal:

Portal
~~~~~~

Fix a data exposure on portals that require sign-in.
The *Portal* rendered tiles to anonymous visitors
and included them in the portal data
before redirecting anonymous visitors to the sign-in page.

When a portal has the *Users are required to login* option enabled,
the *Portal* now redirects anonymous visitors to the sign-in page
before it renders or serves any categories, tiles, folders, or menu entries.
Tiles without a group restriction appear for all users,
so anonymous visitors could see them.

.. _v1.21.0-changes-guardian:

Guardian
~~~~~~~~

Nubus for Kubernetes removes the *Guardian* component
and its container images from the umbrella chart.
This removal prepares an upcoming change
and doesn't alter the behavior of your deployment.
If you set any ``nubusGuardian.*`` values in your custom Helm Chart values,
you can remove them because they no longer have any effect.

.. _v1.21.0-structured-logging:

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

Despite prior announcements,
Nubus for Kubernetes 1.21 doesn't enable structured logging by default.
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 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)
