The Attack Chain: From Leak to Cluster Compromise

Threat intelligence reports document attackers obtaining AWS IAM credentials from developer workstations, enumerating cloud accounts, and accessing Kubernetes clusters. Once inside, they deploy poisoned container images to move laterally and harvest secrets. The MITRE ATT&CK chain: T1552.001 (Credentials in Files) → T1078.004 (Valid Accounts: Cloud Accounts) → T1610 (Deploy Container) → T1496 (Resource Hijacking). This isn't isolated—the Shai-Hulud supply chain attack harvested Kubernetes credentials from CI and developer workstations, feeding this exact pattern.

Three Secret Formats, Three Attack Surfaces

A simplified cluster has three sides: the Kubernetes API server (front door), kubelet APIs on nodes, and container registries (Docker Hub, GitHub Container Registry, ECR, etc.). Three secret formats unlock them:

  • TLS client certificates: used in kubeconfig files for kubectl.
  • JSON Web Tokens (Service Accounts): non-human identities for automation; by default, JWTs have no expiration.
  • Container registry credentials: stored as kubernetes.io/dockerconfigjson Secrets—base64-encoded JSON.

Validating a Leaked Kubeconfig

A kubeconfig contains client-certificate-data and client-key-data (base64-encoded). You can validate with curl:

# Decode key and cert
echo LS0tLS1CRUd...LS0tCg== | base64 -d > key.pem
echo LS0tLS1CRUd...LS0tCg== | base64 -d > cert.pem

# Use against API server
curl --insecure --key key.pem --cert cert.pem https://10.11.12.13:8443/api/v1/namespaces

A successful response means the credentials are valid.

Exploitation Scenarios

Leaked credentials are almost always over-privileged. Attackers can:

  • Lateral movement: deploy a privileged pod, escalate from container to node.
  • Persistence: create or alter a service account to obtain a long-lived JWT.
  • Credential access: dump every Secret object in every namespace—chain reaction from one credential to many.

GitGuardian found one valid JWT from a public Docker image that gave cluster access. That cluster's Secrets contained valid registry credentials, which opened private Docker Hub images and private GitHub organizations.

The Public Leak Data

GitGuardian scanned public GitHub and Docker Hub in fall 2025 for the three secret formats and validated every match.

Kubernetes API Server Credentials

  • 44 unique active clusters; four had >10 nodes, one had >200 nodes (production environment).
  • 30% exposed for over two years; oldest valid leak from 2021.
  • Only 10% of leaked secrets had been deleted from source; rest still sitting there—typically because the developer deleted the commit but never rotated the credential.
  • Valid JWTs were almost exclusively on Docker Hub, not GitHub. Theory: certificates leak via committed kubeconfigs; JWTs leak when service accounts are baked into container images during CI.

Container Registry Credentials

  • 2,034 registry credentials with resolvable hostnames.
  • Provider breakdown: 1,025 Docker Hub, 480 GitHub, 276 Quay, 249 GitLab, 59 Azure.
  • 46% still valid.
  • 309 private Docker Hub images discovered.
  • 730 private GitHub repositories accessible—not from a GitHub leak, but from a Kubernetes Secret leak.
  • Some leaks from 2022 still valid.

Disclosure

GitGuardian identified and contacted 11 companies: 7 for API server leaks, 4 for registry leaks. The hardest part was finding the right person—RFC 9116 (/.well-known/security.txt) would help.

Hardening: No Excuses

None of these mitigations are exotic:

  • Network isolation: Don't expose the API server to the internet. Every major cloud provider has settings for this.
  • Logging and monitoring: Log every authenticated request; alert on suspicious activity via your SIEM.
  • Short-lived credentials: If public access is required, plug into an OIDC provider (AWS IAM, Azure AD, Okta). Exposure window goes from years to hours.
  • Least privilege: Bind service accounts to their namespace, not the whole cluster.
  • Private registries: Use private registries, not public ones for private artifacts.
  • Read-only credentials: Clusters only need pull, not push or repo scope on GitHub.
  • Revoke at decommission: Registry credentials often outlive clusters.

From Research to Product

GitGuardian tuned its detection engines for TLS certificates, JWTs, and container registry credentials. In Q1 2026 alone, those detectors found nearly 2,000 new Kubernetes secret leaks on GitHub; 28% valid at leak time.

Leaked Kubernetes secrets are diverse, misconfigurations amplify risk, and lateral movement is real. The hardening recommendations are well-documented—the work is in applying them and catching leaks early.

This post is based on the talk "All You Can Leak: Real Tales of Publicly Leaked Kubernetes Secrets" at BlackAlps 2025.