Mon, 26 Oct 2026
← VoltarAn automated campaign is using stolen GitHub tokens to plant workflows that print a repository's secrets into its GitHub Actions logs, which the attackers then download before deleting the runs. The attacks have succeeded in private repositories and GitHub Enterprise environments, according to an an
An automated campaign is using stolen GitHub tokens to plant workflows that print a repository's secrets into its GitHub Actions logs, which the attackers then download before deleting the runs. The attacks have succeeded in private repositories and GitHub Enterprise environments, according to an analysis by cloud security company Wiz. A GitHub safeguard that pauses suspicious workflow runs stopped every public-repository run Wiz checked, but it does not cover private repositories or GitHub Enterprise Server. Each workflow sits on a new branch named ci-sync- followed by six random characters.
Deleting a branch, or the run it started, does not undo the exposure. Every secret the repository could read should be rotated, and the token that pushed the branch revoked. Wiz has tracked the campaign since September 15 and calls it Gheist, after the user agent gheist that the attackers' tool sends with GitHub API requests. Wiz has recovered more than 13,500 planted branches from more than 850 compromised accounts, from personal projects to the private repositories of enterprise organizations.
Wiz's analysis does not say how many organizations had secrets exposed. In private repositories and on GitHub Enterprise Server, GitHub audit logs show runs on the planted branches finishing and then being deleted by the gheist user agent. AWS CloudTrail logs show the organization's own workflows also running on those branches and assuming AWS roles, a sign that GitHub Actions ran there without approval. In enterprise organizations, the tool cycled through tokens from several users and automation accounts within minutes and cloned private repositories before planting the workflow.
Hours later, cloud credentials from the same organization were used to enumerate AWS Secrets Manager. Wiz's analysis does not say where those credentials came from or who used them. As of October 24, the campaign was still running and changing. About two-thirds of the accounts involved were no longer available on GitHub.
Wiz reported the activity to GitHub and says their disappearance likely reflects a response. Anyone with write access to a GitHub repository can read every secret configured in it, according to GitHub's documentation. A stolen token with that access is enough. For each repository a token can reach, the tool creates a ci-sync- branch and commits one file, .github/workflows/sync-check.yml, with the message ci: sync config.
The commit is unsigned and includes the token owner's name; pushing it starts the workflow. The workflow prints the job's environment and every secret the job can read, encoded in base32. GitHub masks secrets in logs, but its documentation says this is not guaranteed once a value has been encoded or otherwise changed. Wiz says the base32 text no longer matches the original secret, so it prints in full.
The workflow sets an empty permissions block. That limits the job's GITHUB_TOKEN, which the attackers do not need, and does not stop the job from reading secrets. One version of the tool also runs a job for each deployment environment in the repository, so secrets limited to those environments print too. These are often production credentials, according to Wiz.
The tool then downloads the log through GitHub's API and deletes the run seconds later. Because the secrets leave through GitHub itself, there is no attacker server or outbound connection to block. Since July 28, GitHub has held workflow runs it identifies as potentially malicious until a collaborator with write access approves them. GitHub says the hold "currently applies to public repositories on github.com only" and that GitHub Enterprise Server does not have it at this time.
Every public Gheist run Wiz checked, across all versions of the tool, was still waiting for approval, so its payload never ran. The hold only catches runs that GitHub flags. A new variant of GhostAction, a separate campaign, ran in public repositories until GitHub began blocking it on October 9, according to research from security company GitGuardian. Wiz says Gheist is distinct from GhostAction, which uses different workflow files.
Around October 19, one version of the tool began pushing a second job meant for self-hosted runners, the machines organizations run themselves to process GitHub Actions jobs. It appears to target only repositories that have such a runner registered. The job is written to search the runner machine for credentials, including 31 types of tokens: private keys, process environments, AWS instance role credentials, runner credential files, and the Kubernetes service account token. Wiz describes the job as buggy, and its analysis reports no successful run.
The sources Wiz could trace for the stolen tokens include infostealer logs and tokens exposed in earlier supply-chain attacks, such as the March compromise of the Trivy vulnerability scanner. Other attackers also use the same accounts. On October 6, 391 accounts, many of them also used by Gheist, renamed about 1,461 repositories to appear to be cracked software and spread malware. The renaming wiped 610 of the planted branches.
Some victims also appear to be infected with PolinRider, malware that researchers have linked to North Korea. On October 19 and 20, three of them re-pushed their Gheist commits with a loader added to a vite.config.js file. Megalodon, a campaign that pushed secret-stealing workflows into thousands of GitHub repositories in May, had also hit 57 of the accounts. Wiz recommends these checks: OIDC lets workflows sign in with short-lived tokens instead of stored cloud keys.
By default, a token's subject includes the branch name only when the job does not use a deployment environment, according to GitHub's OIDC documentation. The published indicators are: Versions of the workflow that list a repository's deployment environments vary by repository, so they have no fixed hash. Wiz advises these steps for an affected repository: To make a stolen token less useful, Wiz also recommends these steps: A job cannot read an environment's secrets until a required reviewer approves it, according to GitHub's documentation. Learn how to close critical identity visibility gaps in your SOC, detect hidden threats, and accelerate incident response across human, machine, and AI identities.
Learn how to assess AI threat readiness, strengthen attack surface visibility, and prepare security operations for emerging threats in this practical webinar. Get the latest news, expert insights, exclusive resources, and strategies from industry leaders, all for free.