Anand Naidu is a seasoned development expert who bridges the gap between sophisticated backend architecture and the high-stakes world of cloud security. With a deep understanding of how modern CI/CD pipelines function, he has spent years helping organizations harden their delivery workflows against increasingly creative threats. Today, we sit down with him to discuss “Gheist,” a recent campaign that weaponizes the very automation tools developers rely on to secure and deploy their code. We will explore the mechanics of secret exfiltration through legitimate APIs, the vulnerabilities inherent in self-hosted runners, and why traditional secret masking is no longer enough to protect sensitive credentials.
The “Gheist” campaign represents a shift toward using the infrastructure itself as a weapon, specifically by turning GitHub Actions into a credential-harvesting service. How are these actors managing to stay under the radar while operating at such a massive scale?
The brilliance, or rather the deviousness, of the Gheist campaign lies in how it mimics legitimate developer activity to avoid triggering traditional security alarms. Since September 15, we have seen this actor plant over 13,500 malicious branches across more than 850 compromised accounts, including high-value private enterprise repositories. They use stolen GitHub tokens to gain initial entry, but instead of making a loud exit with the data, they deploy a workflow named “sync-check” that executes within the victim’s own environment. Because the harvested secrets are retrieved directly through GitHub’s own API, there is no suspicious outbound connection to a known malicious domain for a firewall or EDR to flag. It creates a closed loop where the platform’s own features are used to exfiltrate the data, making it incredibly difficult for standard network monitoring tools to spot the theft in real-time.
One of the most striking aspects of this attack is how it bypasses GitHub’s built-in secret masking by using Base32 encoding. Could you walk us through why this simple transformation is so effective against modern CI/CD security features?
GitHub’s secret masking is designed to recognize and redact sensitive strings only when they appear exactly as they are stored in the repository settings. The Gheist actors realized that by simply encoding these secrets into Base32 before printing them to the execution logs, they could fundamentally change the string’s signature. Because the encoded version no longer matches the original secret verbatim, the masking mechanism fails to recognize it, allowing the sensitive data to be printed in plain sight within the logs. This wasn’t just a random choice; by targeting deployment environments like production, they could systematically harvest environment-specific credentials that are often more sensitive than repository-level keys. Once the “sync-check” job finishes printing these encoded strings, the attacker pulls the logs via the API, decodes them locally, and deletes the workflow run within seconds to wipe the digital footprint.
While GitHub has implemented collaborator approval for workflows in public repositories, the report notes that private repositories and GitHub Enterprise Servers remain vulnerable. Why does this gap exist, and what does it mean for the “blast radius” of a compromised enterprise account?
The protection GitHub introduced essentially acts as a gatekeeper for external contributions to public projects, but it assumes a higher level of inherent trust within private and enterprise environments. In an enterprise setting, the assumption is that if you have write access to a repository, your actions are authorized, which is exactly the blind spot Gheist exploits. When an attacker successfully compromises a single enterprise account, the blast radius expands rapidly because they can move laterally into private repositories that often contain the “crown jewels” of a company’s infrastructure. We are seeing these actors target not just simple API keys, but the very credentials used to run production systems, which means a single compromised token can lead to a full-scale takeover of a company’s cloud environment. The lack of mandatory approval for workflows in these private spaces creates a highway for attackers to execute code and harvest secrets without a second pair of eyes ever seeing the malicious pull request or branch.
As the campaign evolved, the actors began targeting self-hosted GitHub Actions runners with a “sync-host” job. What specific risks do self-hosted runners introduce that might not be present in GitHub-hosted environments?
Self-hosted runners are a much bigger prize for an attacker because they provide a foothold directly into the victim’s internal network and host operating system. The Gheist “sync-host” job specifically goes after the “low-hanging fruit” on these machines, such as private keys, environment files, and cloud credentials stored in the file system. Beyond just files, these malicious workflows attempt to access the Docker socket and Kubernetes service-account tokens, which can allow an attacker to escape the container and compromise the entire cluster. They even try to query cloud instance metadata to snag IAM roles, effectively turning a simple GitHub Action into a launching pad for a full-scale cloud infrastructure breach. Unlike GitHub-hosted runners, which are ephemeral and wiped after each run, self-hosted runners often persist, meaning any backdoors or configurations changed by the attacker could have long-lasting consequences for the organization’s security posture.
For security teams currently auditing their environments, what are the most critical forensic markers they should look for to determine if they’ve been hit by this specific campaign?
The most immediate red flag is the presence of branches following a specific naming convention: “ci-sync-” followed by a string of six random characters. You should also be scanning your commit history for titles like “ci: sync config,” as these are the hallmarks of the Gheist deployment strategy. However, detection is only half the battle; because these actors delete their workflow runs almost immediately, you need to look at your GitHub audit logs for high-frequency creation and deletion of workflows. If you find evidence of this activity, you must assume that every secret accessible to that workflow—whether at the repository, organization, or environment level—has been compromised. Rotating these secrets is a massive undertaking, but simply deleting the malicious branch does nothing to mitigate the risk once those tokens have been printed to a log and scraped by an API.
What is your forecast for the evolution of CI/CD pipeline security over the next few years?
I expect we will see a fundamental shift toward “Zero Trust” pipelines where no workflow is allowed to execute or access secrets without explicit, context-aware authorization. The days of treating CI/CD as a “set it and forget it” automation tool are over, and we will likely see platforms move toward mandatory cryptographic signing for every single workflow file to prevent unauthorized modifications. We will also see the rise of more intelligent, behavior-based monitoring that flags unusual patterns—like a workflow suddenly encoding data in Base32—rather than just looking for static secret strings. Ultimately, the industry will have to move away from long-lived secrets in favor of short-lived, dynamically generated tokens that expire before an attacker can even finish scraping the logs. Security won’t just be an “add-on” to the pipeline; it will become the very fabric upon which the pipeline is built, ensuring that every automated step is as scrutinized as the code it is deploying.
