kubernetes-client/python: kubernetes.aio Rename and a v36 Auth Fix
This week the kubernetes-client/python repo merged its long standing kubernetes_asyncio code into the main package and pushed a quiet but important auth fix for v36 of the SDK. If you load configs in production or run async code against the apiserver, both changes affect you.
asyncio code now lives at kubernetes.aio
For years the project shipped an external companion repo called kubernetes_asyncio that mirrored the sync client. Last week the maintainers finished moving its code into this repo, under a nested module: kubernetes.aio. The directory at the old top level path kubernetes_asyncio/ has been deleted.
The work landed across nine commits on 2026 May 22. The ones worth pointing at:
- Auto generated aio package nested under kubernetes produces the new module by running
update-client-asyncio.sh. - Added aio/config, added aio/utils, and added aio/e2e_test move the hand written config loader, the YAML helpers, and the end to end suite under the new layout.
- Removed the kubernetes_asyncio directory deletes the legacy mirror in a single commit. The 562k/563k insertion and deletion stat for the whole window is dominated by this one.
- Updated scripts and README rewires
setup-asyncio.py,scripts/release.sh, and the README example so they import fromkubernetes.aio.
The new code path is straightforward:
import asyncio
from kubernetes.aio import client, config
from kubernetes.aio.client.api_client import ApiClient
If you depend on the external kubernetes_asyncio package on PyPI, nothing changes for you today. The new namespace lives inside the kubernetes wheel and is not yet a drop in replacement for that release stream.
Asyncio support is flagged experimental
A separate commit, updated CHANGELOG to state that asyncio package is experimental, adds an explicit warning to the v1.36 release notes:
Asyncio package is experimental currently, breaking changes may be introduced in future releases.
Read that as: do not pin production code paths to specific call patterns yet. The shape of kubernetes.aio.client will likely shift before it stabilizes. If you ship code that imports from kubernetes.aio, plan for at least one minor version that breaks you.
v36 broke Bearer token auth, and now it is fixed
The second theme is a real production bug. v36 of the SDK rewrote Configuration.auth_settings() so the bearer token credential is looked up at api_key['BearerToken'], matching the OpenAPI security scheme name. The in cluster and kubeconfig loaders were not updated. They still wrote the token at api_key['authorization'], the v35 key.
The visible symptom: every call to load_incluster_config() on v36 produced a Configuration whose auth_settings() returned no credential, so outgoing requests went out without an Authorization header. The apiserver then treated them as system:anonymous and rejected RBAC protected calls.
The fix landed in two commits:
- Write api_key[‘BearerToken’] so v36+ SDK auth works writes the token under both
'authorization'(v35) and'BearerToken'(v36+) in all three affected loaders. A regression test inincluster_config_test.pydrives a realApiClient.update_params_for_auth()against a freshly loaded Configuration and asserts the resulting headers contain anAuthorizationentry. That is the end to end invariant v36 quietly broke. - Drop the dual write and replace authorization with BearerToken follows up on review feedback. The
openapi-generator6.6.0 upgrade declared the rename a breaking change in the project CHANGELOG, so the dual write was dropped. The loaders now write onlyBearerToken.
The three files touched in the fix are all worth knowing about if you maintain config loading code:
kubernetes/base/config/incluster_config.pykubernetes/base/config/kube_config.pykubernetes_asyncio/config/incluster_config.py
If your code reads api_key['authorization'] after load_kube_config() returns, that key is gone now. Switch to api_key['BearerToken'].
CI and tox plumbing followed the rename
The smaller but visible plumbing changes:
- Used kubernetes.aio in github workflows repoints the end to end job in
.github/workflows/e2e-master.yamlat the newkubernetes/aio/e2e_testpath. tox.iniwas updated in the same commit so the default pytest run ignoreskubernetes/aio/e2e_testinstead ofkubernetes_asyncio/e2e_test.- Used kubernetes.aio path in examples updates the three sample scripts under
examples_asyncio/(in_cluster_config.py,list_pods.py,patch.py) so they import from the new module.
Mechanical, but worth knowing about if you copy any of these examples into bootstrap code.
What to watch
- If you still pin v35 of the SDK, do not pull the latest config loaders without auditing any code that introspects
api_key['authorization']. That key is no longer written. - Treat
kubernetes.aioas preview. The maintainers flagged it experimental in the CHANGELOG for a reason. - Watch for follow up commits to
kubernetes.aiothat round out the rest of the legacykubernetes_asynciosurface (resources, watch helpers, leader election). They are not all in yet.
Where to read more: the repo lives at github.com/kubernetes-client/python, and the relevant notes are pinned under v1.36 in CHANGELOG.md.