Replace Long-Lived CI Secrets with Teleport Machine ID
Replace long-lived CI secrets with Teleport Machine ID. tbot gives your pipeline a short-lived, identity-bound certificate instead of a static kubeconfig or SSH key.
25 Jul 2026, 08:12 UTC

Your CI system probably holds a static service-account token, an SSH key, or a database password in its secret store. That credential was created once, has no expiry, and grants standing access to production long after the build that needed it has finished. It leaks into debug logs, gets copied into artifacts, and sits in the secret manager with no clear owner. When someone leaves the team, nobody remembers to rotate it.
The fix is not a better vault. The fix is to stop storing a credential at all and instead give the workload its own identity.
The identity shift: from stored secrets to workload identity
Teleport Machine ID (tbot) runs as a small agent next to your CI job. Instead of presenting a stored secret, tbot authenticates to your Teleport cluster using a join method—such as a GitHub Actions OIDC token or a Kubernetes service-account token—and receives short-lived certificates in return.
Those certificates are bound to a Teleport role. If the role only allows read access to a specific Kubernetes namespace, the certificate only permits that. Every use is logged centrally under the bot's identity, so you replace a shared, anonymous service account with per-job attribution.
Worked example: GitHub Actions deploying to Kubernetes
Suppose you have a GitHub Actions workflow that deploys to a production namespace. Today it probably reads a static kubeconfig from GitHub secrets. You can replace that with a narrowly scoped bot.
First, create a role that limits the bot to the exact resources it needs. Run this on a machine with tctl access and cluster admin rights:
kind: role
version: v5
metadata:
name: ci-deployer
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: pod
namespace: production
name: '*'
Apply it with tctl create -f role.yaml. Next, create a bot that assumes this role:
kind: bot
version: v1
metadata:
name: github-deployer
spec:
roles: ['ci-deployer']
Apply it with tctl create -f bot.yaml. Then configure a GitHub join token so the bot trusts your repository's OIDC tokens. The exact resource shape and tbot flags have changed across Teleport releases, so verify the github join method syntax against your deployed version.
In the workflow, grant the job id-token: write permission and run tbot with a Kubernetes output. The agent writes a short-lived kubeconfig to a destination directory. Your deploy step then points KUBECONFIG at that file. When the job ends, the certificate expires. There is no static token in GitHub secrets to rotate or leak.
The trade-off: Teleport is now on the critical path
This approach moves the failure domain. If your Teleport auth service is unreachable, new certificates cannot be issued. Already-issued certificates remain valid until their TTL expires, but new jobs will fail.
TTL selection is therefore a balance. A five-minute certificate is excellent for security but will break a two-hour deployment if tbot cannot renew it. A twelve-hour certificate is more resilient but weakens the benefit. For most CI jobs, a TTL that comfortably exceeds the job duration—plus a small buffer—is the pragmatic choice.
A second limitation is tool compatibility. Not every CLI or SDK accepts short-lived credentials cleanly. Some tools cache credentials aggressively or expect a file that never changes. Test the specific deploy tool in your pipeline before committing to the migration.
Rollout and verification
Do not migrate every job at once. Pick one high-value pipeline that still uses a static secret. Create a narrowly scoped bot, prefer a secretless join method if your platform supports it, and set a short TTL.
After the job runs, verify the result. Run tbot status on the CI runner and confirm the identity, roles, and certificate expiry it reports. Decode the generated client certificate with openssl x509 -in kubeconfig.crt -noout -dates and check that the NotAfter timestamp matches your configured TTL. Trigger a deployment and confirm a matching audit event appears in the Teleport cluster.
Finally, test the failure mode. Disable the bot with tctl and confirm the next job fails fast rather than falling back to a stale credential. If the job hangs or uses a cached file, your TTL or output configuration needs adjustment.
Bottom line
Long-lived CI secrets are a liability you can eliminate. Teleport Machine ID replaces them with identity-bound, short-lived certificates that expire with the job. The cost is operational: you must treat Teleport as critical infrastructure, monitor its auth service, and choose TTLs that balance security against resilience. Start with one workflow, verify the audit trail, and expand from there.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.