blog
Your CI credential in one step, and signed releases
A GitHub Actions job can now get its kubelatch credential in one step, with the action picaportelabs/kubelatch-action, instead of the 25 lines of curl and jq you had to copy into every repository. And as of 0.44, every kubelatch release ships signed, with an SBOM that lists what's inside it. Here's how each one works, how to check it, what 0.41, 0.42 and 0.43 brought, and where all of this stops.
Twenty-five lines of curl in every repository
If you've already connected a workflow to kubelatch, you probably used the manual's two bash steps, the ones in GitHub Actions to Kubernetes without a secret: the first asks GitHub for the job's OIDC token, and the second exchanges it at kubelatch, masks the credential and writes the kubeconfig. They work, but they're 25 lines of curl and jq that every team copies into every repository, reviews, and then has to maintain.
With the action, all of that fits in one step:
permissions:
id-token: write
contents: read
jobs:
pods:
runs-on: ubuntu-latest
steps:
- uses: picaportelabs/kubelatch-action@v1
with:
url: https://kubelatch.example.com
- run: kubectl get pods -n default
The action does what those two steps did. It asks GitHub for the job's token with your kubelatch's URL as the audience, exchanges it exactly once, and masks both secrets before it writes anything to the log. It writes the kubeconfig to a directory of its own under RUNNER_TEMP, never to ~/.kube/config, and points KUBECONFIG at it. From then on, kubectl, helm and any tool that reads KUBECONFIG reach the cluster as the bot your trust rule names, and every request lands in the audit log.
It doesn't depend on any kubelatch version: it talks to the same exchange as the curl steps, so it works with any instance that has trust rules. What 0.44 adds is that the Workflow snippet kubelatch fills in after Create rule, and the Example workflow on the CI screen, now use the action. For a new workflow, copy it; in one you already have, swap the two steps for the action's step.
An action you can read end to end
A third-party action runs with your job's permissions, so it's worth reading before you hand them over. It's two short JavaScript files, src/main.js and src/action.js, with no dependencies, under the MIT license. Its tests pass on Linux, macOS and Windows runners, and on Linux and macOS they also check that only the job's user can read the kubeconfig's directory. On a self-hosted runner it trusts the system's certificate store, which is usually where your company's CA lives, and goes out through HTTPS_PROXY if you have one set. If your security policy asks for it, pin it by commit instead of @v1.
When kubelatch refuses the exchange, the action's error carries the reason and a link to the section of the manual that explains it. A 403 because no rule matches tells you what a rule has to match: the owner and repository ids, the ref and the environment. A 401 almost always means url isn't exactly the server's.
If your organization allows only its own actions, the two curl steps are still in Credentials for GitHub Actions, and they work just the same.
Signed releases, with their SBOM
As of 0.44, every kubelatch release is signed with cosign and carries its SBOMs in CycloneDX 1.6:
- The SHA-256 checksums file is signed. It covers every
.tar.gzand SBOM of the release, so that one signature checks any binary you download. - The image
ghcr.io/picaportelabs/kubelatchand the chart are signed, and the image carries the server's SBOM as a signed attestation. - There's one SBOM for the server, with its Go modules and the web interface's npm packages (minus the development ones), and another for the CLI.
Checking the image before you deploy it takes one line, with cosign 3 or later:
cosign verify --key cosign.pub ghcr.io/picaportelabs/kubelatch:0.44.0
The public key is printed in Verify a release. Keep that copy next to your pipelines and always check against it: if you fetch it from the same place as the release, whoever could swap one could swap the other. The same page shows how to check the binaries and how to pull the SBOM out of the image for Dependency-Track, Grype or Trivy.
I'm signing releases and publishing their SBOMs now for two reasons. With the SBOM in your Dependency-Track, you hear about a vulnerability in one of kubelatch's dependencies without waiting for me to tell you. And from 11 December 2027, the EU's Cyber Resilience Act requires manufacturers to draw up a machine-readable SBOM; it doesn't require them to publish it, and kubelatch publishes it anyway.
What 0.41, 0.42 and 0.43 brought
As of 0.43, Audit and My activity show the command behind each request. A row reads patch deployments/api (shop) followed by via rollout restart, and the requests of one kubectl run fold into a single row. The command is the one kubectl itself declares, from 1.22 on; helm, k9s and Lens declare none, and their rows stay as they were. Audit and retention has the details.
0.41 lets you decide several agent approvals at once: in Agents, tick the rows and approve or deny them with one confirmation. A batch only groups writes that share the agent, cluster, tool, resource and namespace. Everything else is still approved one at a time, with its diff in front of you.
On a phone, My access now shows one folded block per cluster, as of 0.42. And the local tutorial's docker-compose.yaml no longer pins a version: it runs whatever you put in KUBELATCH_VERSION, so the server matches the CLI you downloaded.
The full notes for every release, in English and Spanish, are in Releases.
What this does not solve
- The action doesn't revoke the credential when the job ends. The runner deletes the kubeconfig after the job, but the credential stays valid until it expires, after one hour by default: if a step of the job copied it, the copy works until then. To cut it short, an administrator revokes it in Credentials.
- Signatures start with 0.44.0: 0.43.0 and older carry neither signatures nor SBOMs, only the checksums file.
- The image's SBOM covers what kubelatch adds to its base image,
gcr.io/distroless/static-debian12, not the base itself. For that layer, run your scanner on the image as you always have.
Try it
If you already run kubelatch, swap the two steps in your workflow for the action, following Credentials for GitHub Actions; you don't need to upgrade for that. To move to 0.44, check the image and the chart first with Verify a release, then upgrade as usual with helm upgrade: the database migrates itself at startup, and the rollout cuts any open exec and port-forward. In Free, bots and trust rules have no limit.
If you don't have it yet, the local tutorial gets it running on your machine, with a throwaway kind cluster, in about fifteen minutes, plus the first downloads.
kubelatch is developed at Picaporte Labs, in Spain. If anything doesn't match what you see, write to me at hola@picaportelabs.com or hello@kubelatch.com.