The 2026 Infrastructure Identity Survey: State of AI Adoption
Read Survey
Teleport logoGet a Demo

Home - Teleport Blog - DevOps Credential Hygiene: How to Eliminate CI/CD Secrets with Teleport

DevOps Credential Hygiene: How to Eliminate CI/CD Secrets with Teleport

by Meina Ghafouri Dec 22, 2025

DevOps Credential Hygiene: How to Eliminate CI/CD Secrets with Teleport

Static credential practices — where certificates, keys, and tokens persist for months or years and are manually rotated — create systemic risk in DevOps pipelines.

Rotating these secrets is time-consuming and costly. In fact, organizations may spend dozens of hours and involve multiple teams to rotate a single credential. Manual rotation quickly becomes impractical across thousands of service accounts.

In this post, you will learn:

  • Why static secrets and rotation does not scale
  • How short-lived certificates and workload identity reduce risk
  • How Teleport replaces static DevOps secrets — and how to get started

Risks of Static Secrets

Leaked secrets are easy to exploit. Attackers who obtain an API key or token can impersonate legitimate services and pivot laterally.

Modern DevOps pipelines are inundated with secrets like SSH keys, API tokens, database passwords, and environment variables that can be found everywhere in your infrastructure:

  • Code repositories — In source code and configuration files that embed API keys or secrets
  • CI/CD pipelines — In build and deployment systems that inject secrets via environment variables or configuration files
  • Application servers — In runtime environments that load secrets from files or environment variables, and use them to authenticate to external APIs or databases
  • External services — In systems accessed via API keys or mutual TLS with long-lived certificates

The more places secrets exist, the harder it becomes to rotate reliably — and the easier they become to steal.

The Certificate Lifespan Trade-Off: Long vs. Short-Lived

Even when teams avoid raw API keys, certificates can recreate the same problem if they last too long. Like keys and tokens, certificate lifetimes require balancing security, resilience, and operational overhead.

Long-lived certificates

Long-lived certificates reduce renewal frequency, which can lighten operational load:

  • Certificate authorities, humans, and programs handle fewer renewals.
  • The network sees fewer renewal requests.
  • Workloads tolerate outages more easily if they cannot renew due to a transient network issue.

The trade-off is that long-lived certs significantly expand the window of exploitation. If an attacker compromises a private key, they may be able to impersonate that client undetected for the certificate’s entire lifespan.

Short-lived certificates

Short-lived certificates reduce this blast radius significantly:

  • If an identity document is stolen, it remains valid for less time.
  • Fewer outstanding identity documents exist at once, which simplifies tracking and auditing.
  • Certificate revocation lists (CRLs) stay smaller, and some environments can avoid relying on CRLs entirely.
  • Long-lived “forgotten” credentials become harder to accumulate.

However, this requires the ability to reliably and automatically renew and expire certificates.

How to Implement Dynamic Secrets at Runtime

Best practice points towards short certificate lifetimes with reliable, automated renewal so security improves without adding fragility.

This aligns directly with OWASP’s recommendation: dynamic secrets that expire automatically.

“When an application starts it could request its database credentials, which when dynamically generated will be provided with new credentials for that session.” OWASP, Secrets Management Cheat Sheet

This approach effectively removes long-lived API keys and secrets from code. Ensuring privileges are granted per-session based on role and automatically expire increases alignment with Zero Trust and the principle of least privilege.

Teleport implements this approach by:

To demonstrate what this approach looks like in action, let’s first compare a typical “before” pattern that loads an API key and long-lived certs with an “after” pattern that pulls short-lived identity at runtime.

​Before: Static Secrets Everywhere

The following sample demonstrates a Go application that retrieves an API key from an environment variable and utilizes a long-lived certificate to establish a connection to an external API.

This pattern is typical in many services that embed API keys for application‑level authentication:

// before/main.go
package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
)

// loadClientTLSConfig loads a long‑lived certificate from disk.
func loadClientTLSConfig(certFile, keyFile, caFile string) (*tls.Config, error) {
    cert, err := tls.LoadX509KeyPair(certFile, keyFile)
    if err != nil {
        return nil, fmt.Errorf("failed to load client certificate: %w", err)
    }
    caCert, err := ioutil.ReadFile(caFile)
    if err != nil {
        return nil, fmt.Errorf("failed to read CA file: %w", err)
    }
    caPool := x509.NewCertPool()
    caPool.AppendCertsFromPEM(caCert)
    return &tls.Config{
        Certificates:       []tls.Certificate{cert},
        RootCAs:            caPool,
        InsecureSkipVerify: false,
    }, nil
}

func main() {
    apiKey := os.Getenv("EXTERNAL_API_KEY")
    if apiKey == "" {
        panic("EXTERNAL_API_KEY is not set")
    }
    // Load long‑lived certs for mutual TLS
    tlsConfig, err := loadClientTLSConfig("client-cert.pem", "client-key.pem", "ca.pem")
    if err != nil {
        panic(err)
    }
    client := &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}
    req, _ := http.NewRequest("GET", "https://api.example.com/data", nil)
    req.Header.Set("Authorization", "Bearer "+apiKey)
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Printf("response: %s\n", string(body))
}

In this example:

  1. The API key is stored in an environment variable and passed as an HTTP header.
  2. The TLS certificate is loaded from disk and rarely rotated.
  3. If the API key leaks, attackers can perform requests on behalf of the application.
  4. Similarly, if the certificate’s private key is compromised, an attacker can impersonate the client until the certificate expires.
Diagram of how code and configurations contain API keys and long‑lived certificates, and secrets flow from the repository to the application and external services.

This model introduces several risks and operational challenges:

  • Secrets exist in environment variables or code and are long‑lived.
  • Certificate rotation is manual and infrequent.
  • The application must manage secret loading and token management.

After: Dynamic Identity and No Static Secrets

In the “before” model, the application is responsible for credential management. It loads an API key, stores or mounts a long-lived certificate, and leaves it to humans to ensure both are current.

The “after” model with Teleport flips that responsibility. Instead of using embedded credentials, the workload receives identity at runtime, proves it cryptographically, and expires automatically.

This provides a practical way to become SPIFFE-compliant by aligning with the SPIFFE model of workload identity. The Secure Production Identity Framework For Everyone (SPIFFE) standard defines how workloads should authenticate using short-lived, automatically rotated certificates rather than static secrets.

The below example shows the after model, where the workload identity uses Teleport's Machine ID (MWI) with the Go SDK integration.

// after/main.go
package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "net/http"
)

// Create a `workloadapi.X509Source`
	source, err := workloadapi.NewX509Source(ctx,
		workloadapi.WithClientOptions(workloadapi.WithAddr(socketAddr), workloadapi.WithLogger(logger.Std)))
	if err != nil {
		return fmt.Errorf("unable to create X509Source: %w", err)
	}
	defer source.Close()

	svid, err := source.GetX509SVID()
	if err != nil {
		return fmt.Errorf("unable to get X509SVID: %w", err)
	}
	
	// Log SVID details on startup - this shows identity without API keys
	log.Printf("✓ SVID obtained successfully")
	log.Printf("  SPIFFE ID: %s", svid.ID.String())
	log.Printf("  Certificate expires: %s", svid.Certificates[0].NotAfter.Format(time.RFC3339))
	log.Printf("  Time until expiry: %v", time.Until(svid.Certificates[0].NotAfter).Truncate(time.Second))
	log.Printf("  → No API keys needed - identity is cryptographic")

	clientID := spiffeid.RequireFromString(config.ApprovedClientSPIFFEID)

	tlsConfig := tlsconfig.MTLSServerConfig(source, source, tlsconfig.AuthorizeID(clientID))

In this example:

  1. The application retrieves the current SVID through the Workload API (via X509Source), which means it automatically uses rotated certificates without reading API keys from disk or environment variables.
  2. Workloads perform direct mTLS authentication with each other using these SVIDs, and no Teleport proxy is in the data path.
  3. No API keys or static credentials are needed.
  4. Authentication and authorization happen cryptographically during the TLS handshake by verifying SPIFFE IDs.
Diagram of how Teleport uses dynamic identity and short-lived certificates to eliminate secrets from authentication processes.

The tbot agent runs alongside each workload (as a sidecar or daemon) and handles:

  • Platform attestation, authenticating to Teleport Auth Service using the platform identity (e.g., AWS IAM role, GCP Service Account, Kubernetes ServiceAccount).
  • SVID issuance, receiving short-lived X.509-SVID certificates (valid for ~1 hour) with SPIFFE IDs.
  • Automatic rotation, continuously renewing certificates before expiry.

With Teleport, the application no longer stores an API key. Instead:

  • It relies on Teleport‑issued client certificates and service identity.
  • The application reads certificates from a directory written by tbot and connects to the external API via Teleport proxy.
  • The proxy enforces authentication and authorization policies.
  • The certificate is short‑lived and automatically renewed by tbot.

Certificate Authority (CA) Rotation: The Bridge to Dynamic Trust

In legacy environments, rotating a certificate authority (CA) meant risk, downtime, and broken trust chains. In Teleport, CA rotation is a controlled, zero-downtime process for renewing a cluster’s trust anchors.

While user and workload certificates renew automatically, CA rotation applies only to the cluster’s CAs (host, user, and database) to maintain organizational trust continuity.

During rotation, both old and new CAs remain trusted, allowing existing sessions and workloads to complete safely while new ones begin using the updated (ephemeral) certificates. Administrators can trigger and monitor rotation using either the Teleport Web UI or the tctl auth rotate CLI command.

Why this matters for migration

For teams migrating from static trust models, Teleport’s CA rotation helps phase out brittle, long-lived trust chains and replace them with renewable cryptographic identities. This provides a predictable way to refresh trust anchors while maintaining compatibility with running workloads.

The CA rotation process

Teleport follows a five-phase rotation model that replaces manual CA operations with a safe, automated workflow:

  1. standby — The cluster is in its steady state, and no rotation is running.
  2. init — Teleport generates a replacement CA, but it is not yet active for signing.
  3. update_clients — The Auth Service begins issuing new certificates from the new CA while continuing to trust certificates issued by the old CA.
  4. update_servers — Proxies, Auth, and agents that accept client connections reload their identities and start presenting certificates signed by the new CA; during this phase, clients accept server certificates signed by either CA. When rotating the host CA, Teleport services reload automatically, and OpenSSH hosts must receive new SSH host certificates.
  5. standby — Rotation finishes, the old CA is retired, and all components trust only the new CA.

Regular rotation of machine certificates is automated, and certificates are renewed by tbot before they expire. For any remaining secrets stored in a secrets manager, configure automated rotation (e.g., AWS Secrets Manager’s rotation feature) and implement monitoring to detect unauthorized access.

The Result: Production-Ready Zero Trust

Zero Trust assumes that no human or machine can be implicitly trusted based on its network location. Instead, every actor must present verifiable credentials and is granted only the minimal privileges necessary for their task.

In Teleport, this principle manifests differently for long‑running machines and for short‑lived workflows.

For long-running machines

Persistent services or daemons run on hosts may live for months or years. These machines use tbot to obtain an X.509 certificate that encodes their machine identity and allows principals access based on Teleport roles.

The certificate is automatically rotated and auditable. Access policies define what resources the machine can reach, and the Teleport proxy mediates every connection.

For flexible workflow identities

Teleport issues short‑lived certificates or JWTs to CI/CD jobs, automation scripts, and AI agents at runtime. Each job obtains its own SPIFFE ID and cannot reuse the credentials of another job, enabling granular auditability as AI agents or build pipeline activity are logged with a unique identity.

Because these identities are short-lived and tied to specific roles, the compromise of a workflow credential has a limited impact and no long-term effects.

Conclusion: DevOps Credential Hygiene Starts with Identity

As DevOps pipelines continue to expand, the number of SSH keys, API tokens, and service accounts grows beyond what any manual rotation process can sustain.

Long-lived secrets embedded in code, repositories, or environment files create persistent risks that attackers are quick to exploit.

By adopting Teleport, organizations gain a practical path to SPIFFE compliance, as well as a way to implement granular policy-based access and unify both human and machine access under a single security model.

The result is a stronger security posture and DevOps credential hygiene that scales thanks to standards-aligned identity.

Get Started with Teleport

Ready to purge static secrets from your DevOps pipelines?

Get started with a free trial of Teleport, or request a demo.

background

Subscribe to our newsletter

PAM / Teleport