The final Kubernetes release of the year is with us as v1.26 is being released. As with all Kubernetes releases, this version introduces and builds on several features that can have an impact on cluster security. In this post, we'll look at several of these changes and what they mean for security across your Kubernetes environments.
Perhaps one of the most interesting changes in Kubernetes v1.26 is a new alpha feature that enables Kubernetes users to validate workloads at admission without requiring additional software.
In any production Kubernetes cluster, some form of admission control is necessary to ensure that restrictions on workloads are adequately enforced (for example, to implement image-signing controls). Generally, this has required external software such as Kyverno or OPA Gatekeeper, so it’s interesting to see the Kubernetes project explore the idea of including this functionality within core Kubernetes.
This feature uses Common Expression Language (CEL) templates combined with an in-cluster controller, which could help to reduce the barrier for cluster operators to implement security policies in their cluster and avoid some of the risks of using external admission controllers. It’s worth noting that this version of the feature will only validate admission webhooks; if workload mutation is required, an external product will still be required.
Kubernetes v1.26 continues ongoing work to bring Windows containers up to feature parity with their Linux counterparts. To that end, this version includes a stable release of the Windows host process container feature, which work similarly to privileged containers on Linux, as well as a new alpha-level feature that provides host network support for Windows containers.
In terms of functionality, these are good improvements for the Windows container ecosystem. From a security perspective, however, they do mean that cluster operators using Windows nodes will have to be even more careful about admission control, otherwise they could end up with containers that are able to compromise the underlying node relatively easily as demonstrated here.
This change, which reaches beta level in 1.26, isn’t so much a new feature as an update to how Kubernetes handles service account tokens that will improve cluster security. In order to authenticate to the API server, service accounts have traditionally been assigned credentials based on Kubernetes secrets. A drawback of this approach is that these secrets do not expire, meaning that if one of them is lost or stolen, the only way to revoke access is to delete the service account itself (which may not be easy if it’s a system service account) or rotate the certificate authority keys in the cluster, which is a disruptive operation.
The new approach is to make use of the TokenRequest API to provide service accounts with expiring JSON web tokens (JWT) in place of those secrets. This has the obvious benefit of reducing the risk of an attacker misusing a stolen token due to token expiry. However, it also means that cluster operators will need to review any instances where they are using service account tokens in order to ensure they will still work with these expiring tokens. For example, where a service account token is provided to software running outside the cluster, there will need to be a mechanism to provide new tokens to it, or an alternative approach to authentication will need to be used.
The software supply chain is one area where the Kubernetes project is looking to improve its own security practices. Included in v1.26 is a beta-level update to how Kubernetes release artifacts (i.e. the binaries provided by the project with each version) are signed. Now, releases are signed using cosign (part of the Sigstore project). This will allow consumers of these releases to embed signature verification as part of their release process, reducing the risk of a supply chain compromise.
An example of a script that can carry out the verification process was released by Sascha Grunert. This script downloads kubectl and then uses cosign to verify the signature of the binary.
#!/usr/bin/env bash set -euox pipefail TAG=v1.26.0-rc.1 URL=https://dl.k8s.io/release/$TAG/bin/linux/amd64 BIN=kubectl for EXT in "" .sig .cert; do FILE=$BIN$EXT curl -sSfL --retry 3 --retry-delay 3 $URL/$FILE -o $FILE done COSIGN_EXPERIMENTAL=1 cosign verify-blob $BIN --signature $BIN.sig --certificate $BIN.cert
One of the things that can be surprising when coming to Kubernetes from other multi-user networked systems is that Kubernetes has no concept of a “user” object. Instead, it has multiple authentication mechanisms and assigns usernames and group memberships based on the information provided during authentication. This means that it can be difficult for users to find out what groups they belong to, which is information that is often useful when troubleshooting authorization issues in the cluster.
A new feature, which will be alpha level in v1.26, aims to fill this gap by providing an API endpoint that users can call to get information about themselves after authentication.
Kubernetes v1.26 contains the usual mix of new features and feature improvements that come with each release. Some of the more interesting ones this time are in alpha, so it will be some time before they’re enabled by default. They’re still available for adventurous cluster operators to use and provide feedback on before they graduate to stable.