We told you in last month’s recap that May was going to be busy. It was. The biggest launch of the month is one most platforms treat as plumbing, a support ticketing system, but we built ours from scratch because we think support is where the AI-driven operations story starts. Around it landed a new way to describe where your workloads should run, OIDC-native CI/CD, a fresh CLI, and a same-day mitigation for a Linux kernel CVE that hit the whole ecosystem. Here’s the tour.
A first-party, AI-native support center
On May 13, we replaced the embedded third-party support form with our own ticketing system. The new support center lives inside the Cloudfleet console and is also available through the API, the cloudfleet CLI, and the Cloudfleet MCP server. Tickets are scoped to your organization, so every member shares one backlog instead of fragmenting context across individual email threads.
We want to be honest about why this is the biggest launch of the month, because on paper it sounds like a maintenance project. It is not. Support is where our AI strategy actually begins.
Here is the bet we are making: in the next few years, the day-to-day operation of Kubernetes infrastructure will be driven primarily by AI agents. Not just chat tools that help an engineer write a kubectl command, but agents that actually drive the platform, opening tickets when they need help, gathering context, applying fixes, and following up. We are building Cloudfleet for that world. Every surface we ship has to be programmable, structured, and reachable by an AI assistant, not just by a human in a browser tab. The MCP server in our CLI was the first big move in that direction. The support center is the next one.
We did look at the alternatives. We evaluated the obvious third-party support platforms (the big help desks, the Slack-integrated ones, the developer-tool-shaped ones) and tested how cleanly they could be wired into the rest of the Cloudfleet experience. They are all good products. None of them gave us what we actually wanted:
- Structured context, not opaque text. A third-party ticketing system sees a ticket as a free-form thread. Our system sees it as a ticket attached to a specific organization, cluster, region, fleet, and workload, with the cluster’s recent events and state available in the same data model. That structure is what makes an AI assistant useful instead of just clever.
- Native MCP and API surface area. Because the support center is a first-party Cloudfleet resource, it shows up alongside clusters and fleets through the same API, CLI, and MCP server. An AI assistant connected to Cloudfleet can open a ticket, attach the diagnostic data it just gathered, watch for a reply, and act on the response. No glue code, no separate auth, no scraping.
- Authentication and authorization that matches the rest of the platform. Tickets respect the same RBAC and organization boundaries as every other Cloudfleet resource. Bolting a third-party tool onto our identity model would have meant two permission systems to keep in sync, and two places for a misconfiguration to leak context across organizations.
- Operational quality. We support our own platform. Putting the ticket queue inside the platform means the engineers on call see incidents and tickets in the same context, with the same data, and the loop from “customer hit a thing” to “engineer fixed the thing” is dramatically shorter.
The shape of the product follows directly from that bet. You can open a ticket from the console, the CLI, or an AI assistant. You can attach context programmatically. You can subscribe to ticket updates from automation and have a workflow respond to them.
This is not a hypothetical roadmap. It is how support already works on Cloudfleet today, on both sides of the ticket.
On the customer side, a majority of the tickets we now receive are opened by our users’ own AI agents, not by humans clicking a button. An AI assistant connected to Cloudfleet via MCP notices something it cannot resolve on its own, gathers the relevant cluster state, drafts a ticket with the right context attached, and files it. Then it watches for the reply. We did not have to build any of that ourselves; it fell out of having an API and an MCP surface that look the same as every other resource in the platform.
On our side, we’ve built substantial AI agents behind the scenes to handle the other half of the loop. When a ticket lands, our agents pull cluster state, recent events, similar past tickets, the relevant parts of our documentation, and any open incidents, all in real time. They cross-reference that context against everything we know about how the platform behaves, and they draft a response.
No ticket is ever answered without human review. None. This is deliberate, and we are not changing it any time soon. We understand exactly what is at stake when someone reaches out for support, and we are not willing to hand the final word to an AI yet. Every response a Cloudfleet customer sees is read, evaluated, and approved (or rewritten) by a human support engineer before it goes out. The AI is a research assistant and a drafting tool. The judgment is human.
The result is the best of both: customers get answers that are correct, context-aware, and recognizably written by someone who actually understands the situation, but they get them dramatically faster. Our support SLA is meaningfully shorter than it was before the launch, and we can scale our support capacity with the customer base as we grow without sacrificing the quality of the human touch that we think defines good support.
This is the same logic that drove Cloudfleet Container Registry in Q4: every handoff between vendors in your workflow is a place where context, automation, and AI integration break down. Owning the whole path is what makes the AI-native version possible.
Fleet constraints: pin infrastructure decisions to where they belong
The other big May launch is Fleet constraints, which landed on May 3 and is now fully self-service through the console, the API, and the Terraform provider. It’s a small feature on the surface and a meaningful change in how you describe infrastructure on Cloudfleet. It’s also one of the most-requested features we’ve shipped this year. Customers have been asking for it in support tickets, sales calls, and design reviews for months, and the design we landed on is shaped almost entirely by what they told us they needed.
Here’s the problem it solves. Cloudfleet’s node auto-provisioner decides where each pending pod runs by evaluating every Fleet attached to your cluster and every instance type each Fleet could provision. By default that flexibility is the point: a single cluster spanning AWS, Hetzner, OVH, and your own datacenter, scheduling each workload onto whichever cloud and instance type fits best at that moment.
But that flexibility has a cost on the workload side. If a particular workload has to run in a specific cloud (data sovereignty, license terms, GPU model availability, proximity to a managed database, customer contractual requirement, you name it), the only way to express that was to attach the right nodeSelector, nodeAffinity, or tolerations to every pod spec. Three problems with that:
- The constraint lives in the wrong place. A platform team’s decision that “everything in Fleet X must run on Hetzner in Falkenstein” gets encoded across hundreds of pod specs owned by other teams. Easy to miss, easy to drift, almost impossible to audit.
- Application teams need to know the topology. Whoever writes the Deployment has to know which clouds, regions, and instance families exist, and remember the exact label keys for each. This is leaking infrastructure detail into application code.
- The auto-provisioner does more work than it should. Every scheduling decision considers candidates that were never going to be valid. Most of the time this just shows up as noise in scheduling latency; under load it can mean the auto-provisioner spends cycles evaluating instance types in clouds you’d never actually use.
Fleet constraints fix all three. You pin a Fleet to a specific cloud, region, instance family, or any combination of attributes, once, on the Fleet itself. From then on, the auto-provisioner only considers that Fleet for workloads whose intent is compatible with the constraint, and your pod specs stop needing to repeat the same selectors. The constraint lives on the infrastructure object, where infrastructure decisions belong. Application teams describe what they need, the platform team decides where it runs, and the two no longer have to coordinate through copy-pasted YAML.
A few concrete patterns we’ve seen customers adopt in the first weeks of the preview:
- Sovereignty-constrained Fleets. A Fleet pinned to a specific EU cloud and region for workloads that have a GDPR or contractual residency requirement. Drop the workload into the right namespace, done.
- Instance-family-constrained Fleets. A Fleet pinned to Hetzner’s dedicated-CPU
ccxfamily for latency-sensitive services, with a sibling Fleet pinned to shared-CPU families for background jobs. The auto-provisioner stops mixing them. - GPU-class-constrained Fleets. A Fleet pinned to providers and instance types that offer a specific GPU SKU, so AI workloads never accidentally land on a different accelerator with different driver assumptions.
There’s also a quieter benefit: when you add a new cloud or remove an old one from your infrastructure, you change one Fleet, not every Deployment.
The other May 3 launch is auto-provisioning profiles, which let you tune how the auto-provisioner consolidates capacity inside a Fleet. By default, Cloudfleet pursues aggressive cost optimization, disrupting and replacing under-utilized nodes whenever it sees a cheaper layout. With profiles, you can switch to a less invasive policy, for example consolidating only nodes that are already empty, so long-running pods are not evicted for repacking. The two features compose: pin a Fleet with constraints, then pick the consolidation profile that matches that workload’s tolerance for disruption. Profiles are still in private preview and gated through Cloudfleet support while we finalize the API surface.
Native CI/CD with OIDC workload identity
Long-lived credentials in a CI system are a category of mistake our industry should have stopped making years ago. They get committed to repos by accident. They get pasted into chat. They get into stale forks. They get rotated late, or never, because nobody remembers which workflow still depends on them. Their scope is almost always wider than the workflow needs because narrowing it down is annoying. And when you eventually do try to rotate one, you discover three more workflows that were quietly using the same secret. Every platform team has a story like this. Many of them have several.
The numbers back up the war stories. GitGuardian’s State of Secrets Sprawl 2026 report found 29 million new hardcoded secrets leaked to public GitHub in 2025 alone, a 34% year-over-year increase and the largest single-year jump ever recorded. 32.2% of internal repositories contain at least one hardcoded secret. And of the secrets GitGuardian confirmed as valid back in 2022, 64% are still exploitable four years later because nobody got around to rotating them. The CircleCI breach in January 2023 is the cautionary tale every platform team should know: a single compromised engineer laptop forced every CircleCI customer to rotate every secret they had stored on the platform, which for many teams meant weeks of pain and unknowable blast radius.
On May 11, we shipped native CI/CD integration for Cloudfleet clusters that removes the category entirely. GitHub Actions workflows and GitLab CI jobs can now authenticate to your clusters using OpenID Connect workload identity federation, with no long-lived API tokens or kubeconfigs stored in your repositories.
The mechanics are clean: your cluster’s API server trusts GitHub and GitLab as identity providers directly. At runtime, a workflow mints a short-lived OIDC token. kubectl presents that token, and the API server authenticates the workflow as itself, the specific repository, branch, tag, or deployment environment that triggered the run. RBAC and ValidatingAdmissionPolicy can then be bound to those identities for fine-grained access control. Setup details live in the GitHub Actions and GitLab CI integration guides.
OIDC workload identity is how the industry has converged on solving this for cloud APIs. Bringing the same pattern to Kubernetes API access closes a gap that platform teams have been working around with secret-rotation gymnastics for too long.
This is also part of a broader pattern at Cloudfleet that we are quite proud of: the right number of long-lived credentials in your workflow is zero. The OIDC CI/CD integration is the newest entry in a list that already includes:
- Accessing cloud provider APIs from your workloads without hardcoded keys. Every pod on a Cloudfleet cluster gets a short-lived OIDC token mounted at the standard Kubernetes path. You federate that token directly with AWS IAM, GCP Workload Identity Federation, Azure, or any other OIDC-aware identity provider. Your S3, Cloud Storage, and Blob Storage clients authenticate as the workload, not as a baked-in access key.
- Pulling images from Cloudfleet Container Registry without image pull secrets. Cloudfleet clusters authenticate to CFCR automatically. No image pull secrets to create, no registry credentials to rotate, no shared secret to leak.
- Pulling images from AWS ECR and GCP Artifact Registry without hardcoded credentials, either. Authorize a Cloudfleet-owned IAM role on your AWS or GCP account and Cloudfleet pulls from your private ECR or Artifact Registry directly. No long-lived access key to bake into a Secret.
Each of these removes a category of credential from your workflow rather than just rotating it faster. That is the bar we hold ourselves to.
CLI 0.10.0 and publicly signed TLS on the control plane
On May 14, Cloudfleet control plane endpoints started serving publicly signed TLS certificates. The new endpoint_public field on the cluster resource exposes this URL, and Cloudfleet CLI 0.10.0 uses it when generating kubeconfigs.
This change came directly out of the CI/CD work above. While we were building cloudfleet-actions/configure-kubectl, the GitHub Action that pairs with the new OIDC integration, we hit the same wall over and over: every workflow run had to fetch the cluster’s private CA certificate before kubectl could talk to the control plane. That meant every action had to install the Cloudfleet CLI and call an extra API endpoint just to retrieve a certificate bundle. Two more failure modes, two more seconds of latency, and a noticeable amount of YAML in every workflow that wasn’t doing anything except making TLS happy.
We were hearing the same complaint from customers running any kind of automation that talks to a Cloudfleet cluster from outside the cluster: serverless functions, container images, scripts on a CI runner. Wherever the certificate had to be packaged or pulled at runtime, it was friction. Our own tutorial on triggering Kubernetes jobs from AWS Lambda is a case in point: it spends real pages on how to package the certificate with the function, and shouldn’t have to.
When we sat down to fix the developer experience, the honest answer was that the private CA was not actually buying us anything. It was a habit, not a security boundary. The control plane endpoint is internet-reachable by design, the same as every other managed Kubernetes service, and authentication is enforced by short-lived bearer tokens on every request regardless of which CA signs the TLS cert. Switching to a publicly signed certificate for the same endpoint removes the friction without weakening the security model. So that’s what we did.
The practical effect: kubectl no longer needs to trust an embedded private CA bundle to talk to your cluster. Anything that speaks standard TLS works against the control plane without ceremony. Existing kubeconfigs continue to work, but regenerating them with cloudfleet auth update-config picks up the new endpoint and shrinks the kubeconfig considerably.
CLI 0.10.0 also ships a set of authentication fixes that address recurring failure modes:
- Concurrent CLI invocations no longer open a flood of browser windows when the cached token has expired. Parallel invocations coordinate so they share a single browser window and the refreshed token.
kubectlanddockercommands no longer break after an interactive login because of stray output from the browser launcher mixing into the credential helper response.cloudfleet auth configure-dockeris now safe to run repeatedly. Previously, re-running the command would fail with an “already exists” error whenever the CLI binary path had changed since the first run, which happens routinely with Homebrew, Nix, and other package managers that install each version to a new location.- Authentication now works on WSL2 where the CLI cannot launch a Linux browser automatically. The CLI prints the login URL and keeps the callback server running, so you can paste the URL into the Windows host browser and complete the flow.
If you’ve been hitting any of these, upgrade the CLI and they go away.
The Copy Fail mitigation
On May 1, a Linux kernel vulnerability disclosed as CVE-2026-31431, informally “Copy Fail,” landed across the industry. The flaw is in a kernel cryptography component and affects most Linux distributions currently in use, including the Ubuntu kernels that Cloudfleet worker nodes run on. The impact: a local unprivileged user on a node can gain root access.
We rolled out a same-day mitigation through a small DaemonSet that runs in the kube-system namespace of every Cloudfleet cluster. On each node, it disables the affected kernel component and persists the change across reboots. No action was required from customers.
This was a stopgap by design. We’re following up by integrating the same protection into our node provisioning so freshly bootstrapped nodes are protected from first boot, and by adopting upstream kernel fixes as the operating system distributions we use publish them. For background, see the NVD entry and Ubuntu’s advisory.
The broader point: when something hits the whole Linux ecosystem at once, the value of a managed control plane is that the response is one rollout, not thousands of independent on-call pages. The mitigation reached every cluster within hours of the disclosure.
Quiet fixes worth knowing about
A pair of May 22 fixes cleaned up two long-running edge cases in the Kubernetes API server, both of which affected long-running clients like controllers and operators:
- Listing Kubernetes events at a particular resource version could return HTTP 500 after a control plane component was rescheduled. Affected clients would get stuck retrying. The fix makes these requests complete correctly, and affected clients now re-synchronize on their own without a restart.
- A regression caused concurrent updates to the same object to surface as HTTP 500 errors instead of standard HTTP 409 conflicts. Common offenders were controllers that update object status frequently, like node and workload status patches. These conflicts are once again returned as 409s and retried automatically, so writes succeed without surfacing errors.
If you’d built around either of these in your own operators, you can take the workarounds out. The NVIDIA GPU driver on GPU nodes also picked up an update to version 595.0.0 in the same window.
Looking ahead to June
The pattern across the first half of 2026 has been steady: finer-grained control where you need it, fewer surprises from the platform underneath, tighter integration with the tools you already use to ship software, and more of the platform reachable by AI assistants. June will keep pulling on the same threads, with more work on the self-service surface area for auto-provisioning profiles, continued expansion of the new cloud provider integrations from private preview toward GA, and the Kubernetes 1.34 rollout beginning across clusters. We are intentionally not jumping straight to 1.36 even though it is the newest upstream minor; 1.34 has had time to settle, the early patch versions are stable, and that is the version we are comfortable putting in front of customers first.
As always, if there’s a specific topic you’d like to see in a future recap, send us a ticket through the new support center or reach out via your account manager.
