Wiz Research has recovered more than 13,500 planted branches across more than 850 compromised GitHub accounts, all part of one automated campaign it calls Gheist. No software vulnerability was needed: a stolen token with write access was enough, because anyone who can push to a repository can read every secret configured in it.
What happened
For each repository a token could reach, the tool created a branch named ci-sync- followed by six random characters, then committed a single file, .github/workflows/sync-check.yml, with the commit message 'ci: sync config'. Pushing the branch started the workflow, which printed the job environment and the repository secrets after encoding both in base32.
That encoding is the whole trick. GitHub masks secret values in workflow logs only when they appear verbatim, so encoded values print in full. The workflow is also set to permissions: {} , which restricts the job token but does nothing to the secrets context. Where a repository has deployment environments, the tool listed them in a job matrix so production-scoped secrets were printed too. It then pulled the log through GitHub's own API and deleted the run seconds later, which means there is no attacker domain and no outbound connection to block.
GitHub has held potentially malicious workflow runs in public repositories for approval since 28 July 2026, and every public Gheist run Wiz checked sat in action_required. That hold does not apply to private repositories or GitHub Enterprise Server. There, GitHub audit logs show ci-sync runs completing and then being deleted by the gheist user agent, and AWS CloudTrail shows the victims' own workflows running on those branches and assuming roles.
A variant pushed on 19 October added a second job aimed at self-hosted runners, sweeping for 31 token formats including AI provider keys, private keys, .env files and Terraform state, then reaching the host through the Docker socket. Wiz describes that job as buggy and found no successful run. The campaign was still active as of 24 October.
Who is affected
Any organisation whose repositories hold working credentials, which is nearly every organisation that builds or hosts software.
- Teams using GitHub Actions with repository, organisation or environment secrets, particularly in private repositories.
- Anyone running GitHub Enterprise Server, where the approval hold is not available.
- Organisations still issuing long-lived personal access tokens rather than scoped GitHub Apps or short-lived tokens.
- Self-hosted runners with Docker socket access or reachable cloud instance roles.
What to do now
Hunt for ci-sync- branches first, and treat any completed run as a leak rather than an alert.
- Search for branches matching ci-sync- followed by six characters whose only change adds sync-check.yml with the commit message 'ci: sync config'.
- In GitHub audit logs, look for workflow runs on those branches deleted within a minute of finishing, and for API activity from the user agent gheist.
- If your workflows authenticate to AWS with OIDC, check CloudTrail for role assumptions whose session or subject contains a ci-sync- branch. That proves Actions ran on an attacker branch even without GitHub logs.
- On self-hosted runners, look for the files .gdmp_pat, .gdmp_patg and .gdmp_sweep, and for the string gdmp-pivot in job logs.
- Rotate every repository, organisation and environment secret the affected repository could read. Deleting the branch or the run does not undo an exposure.
- Revoke the tokens that pushed the commits, then check those users' machines for infostealers, since that is where the tokens came from.
- Require reviewers on environments that hold production secrets, scope OIDC trust to protected branches, and replace personal access tokens with GitHub Apps or fine-grained short-lived tokens.
What this means for South African businesses
Most South African SMEs do not run GitHub Enterprise, but plenty of local dev shops, agencies and MSPs keep client infrastructure keys in private repositories with no reviewer gate and a personal access token that has never been rotated. The exposure here is not exotic: it is the ordinary setup where one developer's laptop gets an infostealer and a token sitting in a config file can reach twenty repositories. The migration to GitHub Apps and environment reviewers is the difference between one stolen laptop and a full credential reset for every client you host.
Source: Wiz Research, Gheist: attempted scaled abuse of stolen GitHub tokens.
Also on the blog
Next step: If this is on your network or a client's, ask Matthews Enterprises to check exposure.