Gheist uses stolen GitHub tokens to dump Actions secrets from private repos
Wiz Research says the Gheist campaign has planted secret-dumping GitHub Actions workflows on more than 13,500 branches from more than 850 compromised accounts since September. GitHub's approval hold stops it in public repositories, but not in private repositories or GitHub Enterprise Server, where Wiz saw secrets stolen and cloud credentials used.
- Wiz Research says the Gheist campaign has used stolen GitHub tokens to plant a secret-dumping workflow on more than 13,500 branches from more than 850 accounts since 15 September, and it is still running.
- The workflow base32-encodes every secret so GitHub’s log masking misses it, then the tool downloads the log through the API and deletes the run seconds later; there is no attacker server to block.
- GitHub’s 28 July approval hold stopped every public-repository run Wiz checked, but it doesn’t cover private repositories or GitHub Enterprise Server, where Wiz saw runs complete and, hours later, the organization’s cloud credentials used to enumerate AWS Secrets Manager.
- If a
ci-sync-branch shows up in your repositories, rotate every secret the repository could reach: deleting the branch or run doesn’t undo the exposure.
Gheist turns any leaked GitHub token into a secrets dump
Wiz Research reported on 25 October that Gheist, a campaign it has tracked since 15 September, commits a workflow called sync-check to every repository a stolen GitHub token can reach. It pushes a branch named ci-sync- plus six random characters, with the commit message ci: sync config. The workflow prints the environment and toJSON(secrets) in base32, which GitHub’s masking doesn’t recognise. One variant lists deployment environments in a job matrix, so environment-scoped secrets, often production credentials, come out too. The attacker’s workflow even sets permissions: {}, which limits GITHUB_TOKEN but not the secrets context, so it loses nothing.
Wiz recovered 13,500+ planted branches from 850+ accounts, including enterprise private repositories. Since 19 October one variant also targets self-hosted runners, searching for 31 token formats (including Anthropic, Hugging Face, Groq and NVIDIA keys) and using the Docker socket to reach the host, though Wiz says that job is buggy. The tokens Wiz could trace came from infostealer logs and earlier supply-chain compromises, such as the Trivy compromise in March.
Why it matters
Any team whose GitHub tokens have leaked, from users or automation accounts, is exposed, above all in private repositories. Wiz’s hunting signs: ci-sync-* branches, runs deleted within a minute of finishing, the user agent gheist, and cloud role assumptions from ci-sync- branches via OIDC. Its fixes: rotate secrets, require reviewers on production environments, scope OIDC trust to protected branches, and prefer GitHub Apps or short-lived fine-grained tokens.
Public repositories got a guard, private ones didn’t
GitHub’s approval hold blocks suspicious runs until a collaborator approves them, but applies only to public github.com repositories. In dbggr’s view, Gheist’s private-repository successes make the case for extending it, and we’d expect pressure on GitHub to do so. Until then, environment reviewers and branch-scoped OIDC limit the damage, but repository and organization secrets stay exposed to any token with push access.
