Gheist campaign steals secrets from private GitHub repos via Actions logs
Attackers use stolen tokens to plant workflows that dump secrets into logs, bypassing GitHub's public repo safeguards in private and enterprise environments.
A new automated attack campaign named Gheist is exploiting stolen GitHub tokens to extract sensitive data from private repositories. Since mid-September, security researchers at Wiz have observed attackers planting malicious workflows that print repository secrets directly into GitHub Actions logs. These attacks specifically target private repositories and GitHub Enterprise Server instances, where existing automated safeguards are less effective.
What happened
The Gheist campaign operates by using compromised credentials to create new branches in targeted repositories. Each branch follows a specific naming pattern, starting with ci-sync- followed by six random characters. The attackers commit a single workflow file to these branches, which is designed to execute immediately upon push. This workflow accesses the repository's environment variables and secrets, encoding them in base32 format before printing them to the standard output. Because the data is encoded, it bypasses GitHub's automatic secret masking features, allowing the full values to appear in the build logs.
Once the workflow completes, the attacker's tool downloads the log file via the GitHub API and then deletes the workflow run and the branch itself. This rapid cleanup makes detection difficult, as the evidence disappears quickly. Wiz reports that while GitHub has implemented a safeguard that pauses suspicious workflow runs in public repositories, this protection does not currently extend to private repositories or self-hosted GitHub Enterprise Server installations. Consequently, every public repository attempt Wiz analyzed was blocked, but private and enterprise environments remained vulnerable to successful exfiltration.
The scale of the campaign is significant. Wiz has identified more than 13,500 planted branches across over 850 compromised accounts. These accounts range from individual developers to large enterprise organizations. In some enterprise cases, the attackers cycled through multiple user and automation tokens within minutes, cloning private code and planting workflows across several repositories. The stolen tokens often originated from infostealer malware or previous supply-chain compromises, such as the March incident involving the Trivy vulnerability scanner.
Key details
- The campaign uses the user agent string gheist for all API requests.
- Malicious branches are named ci-sync- followed by six lowercase alphanumeric characters.
- The committed workflow file is always .github/workflows/sync-check.yml with the message ci: sync config.
- Secrets are exfiltrated by encoding them in base32 to bypass GitHub's log masking.
- GitHub's automatic hold for suspicious runs currently applies only to public repositories on github.com.
- Wiz has recovered over 13,500 planted branches from more than 850 compromised accounts since September 15.
Background
GitHub Actions allows developers to automate software workflows, such as building and testing code. These workflows often require access to sensitive information like API keys, database passwords, and cloud credentials, which are stored as repository secrets. By default, any user with write access to a repository can read these secrets. When a workflow runs, GitHub attempts to mask known secret values in the logs to prevent accidental exposure. However, this masking relies on exact string matching. If a secret is modified, such as by encoding it in base32 or splitting it into parts, GitHub may fail to recognize and mask it, leaving the raw value visible in the logs.
The distinction between public and private repository protections is critical here. GitHub recently introduced a feature that holds workflow runs from unverified sources for manual approval in public repositories. This acts as a strong barrier against automated abuse in open-source projects. However, this feature is not yet available for private repositories or GitHub Enterprise Server, which many companies use for internal proprietary software. This gap leaves self-hosted and private environments reliant on other security measures, such as strict token management and audit logging, which can be harder to monitor in real-time.
Why it matters
For teams running their own software or managing private codebases, this incident highlights a fragile link in the CI/CD security chain. The assumption that logs are safe because secrets are masked is no longer valid. Attackers are actively using encoding techniques to circumvent these protections. If your organization uses GitHub Actions for deployment, especially with self-hosted runners or private repositories, your secrets are at risk if a token is compromised. The fact that the attackers delete the runs immediately means that traditional monitoring might miss the event entirely unless you have detailed audit logs enabled and actively reviewed.
Furthermore, the campaign demonstrates the cascading effect of token theft. A single stolen personal access token or automation credential can lead to the compromise of an entire organization's cloud infrastructure. In the cases analyzed by Wiz, attackers used the initial access to assume AWS roles via OIDC, potentially gaining broader control over cloud resources. For IT leads and DevOps engineers, this means that securing the CI/CD pipeline is not just about code quality but about protecting the keys to your production environment. The lack of automatic blocking in private repos places the burden of detection squarely on the internal security team.
What you can do
- Search your repositories for branches matching the pattern ci-sync- followed by six characters and delete them if found.
- Rotate all repository, organization, and environment secrets immediately if you suspect any token compromise.
- Review GitHub audit logs for workflow runs on ci-sync-* branches that were deleted within a minute of completion.
- Check cloud provider logs, such as AWS CloudTrail, for role assumptions linked to ci-sync- branch subjects.
- Revoke any tokens associated with compromised accounts and scan the owners' devices for infostealer malware.
- Require manual reviewer approval for deployments to environments containing production secrets.



