- What: GhostAction, the credential-theft campaign that plants a fake "security audit" GitHub Actions workflow with stolen maintainer credentials, ran its largest wave on October 8 and 9, 2026. GitGuardian counts more than 30,000 repositories targeted across about 3,000 users and organizations, roughly 1,900 accounts compromised, and 3,174 secrets the payload tried to extract from public CI.
- Impact: the October payload embeds the repository's named Actions secrets, then greps the working tree and the full git history for thirteen credential patterns, pairs AWS key IDs with the secret keys near them, and posts the lot over plain HTTP to 193.32.204[.]199. GitHub began blocking the workflow from running on October 9, so the October 10 and 12 waves extracted nothing.
- Fix / mitigation: no patch exists because no software flaw is involved. Any repository that carries
security-audit.yml,github_actions_security.ymlorsecurity-check.ymladded since August 31, 2026 is a breach: revoke the credential that pushed it, rotate every secret the workflow could name or find in history, remove the file from every branch and fork, and audit the Actions runs. - Who's at risk: anyone whose GitHub credential sits in an infostealer log, and anyone who forks, mirrors or depends on a repository that does. The attackers reuse secrets that were never rotated after the September 2025 and August 2026 waves.
Start at threat-intelligence.redeyesecurity.com. We covered the first days of this wave on October 11, when Socket had traced 346 repositories to two maintainer accounts. GitGuardian's October 15 report, picked up by The Hacker News the same day, moves the scale by two orders of magnitude and answers the question we keep getting: is there a list I can check my repositories against. There is not. So this post is the list you build yourself, and what we found when we built ours.
What GitGuardian Added on October 15
GitGuardian researchers Gaetan Ferry and Guillaume Valadon put the October 8 and 9 spike at more than 30,000 repositories targeted across about 3,000 users and organizations. Roughly 1,900 user accounts were compromised, and the workflow attempted to extract 3,174 secrets from public repositories' CI. The deployment was phased: the payload went first to 160 victims the campaign had already hit, then, twenty minutes later, to about 28,000 new repositories. That gap is the tell of an operator testing a batch before committing the fleet.
The payload itself moved three times during the wave. The first version added the git history scan, with regular expressions for AWS key IDs, GitHub and GitLab tokens, AI provider keys and cloud API keys. The second captured about two lines of context around every AWS key ID so the key could be paired with its secret. The third retrieved that context during the history scan rather than after it. Batches were labelled in the exfiltration URL, bling, blingnew, monami, new, mnsft, security, which is how the researchers separated the runs.
GitHub began blocking the malicious workflow from running on October 9. New waves with the same payload followed on October 10 and 12 and extracted nothing. GitGuardian calls this wave "more experimental and manual" than the earlier ones, and notes that some of the October victims were also hit in September 2025 and August 2026, which says the operator is working from unrotated secrets as much as from new credentials. The earlier counts for scale: 817 repositories, 327 users and 3,325 secrets in September 2025; 772 public repositories, 373 users and 2,577 targeted secrets between August 31 and September 30, 2026.
The Payload, in Defensive Detail
From Socket and StepSecurity, who both pulled the October file apart. The workflow is .github/workflows/security-audit.yml, named "Security Audit". It triggers on workflow_dispatch and on push with no branch or path filter, so any push to any branch runs it. One job, audit, on a GitHub-hosted runner: a checkout with fetch-depth: 0, which is what makes the history scan possible, then a single step named "Audit".
- Named secrets. The file embeds the repository's own Actions secret names, learned from its legitimate workflows. For kitao/pyxel those were the Cargo registry token, a personal access token and the PyPI credentials. Each generated file is byte-identical apart from that list, so a tool wrote them.
- History sweep. A grep over the working tree, excluding
.git, for thirteen credential patterns in four families: AWS access key IDs, secret keys and session tokens; Anthropic, OpenAI project and OpenRouter keys; GitHub classic and fine-grained tokens and GitLab tokens; Google API, Slack and SendGrid keys. Thengit log -p --all, capped at 200,000 lines, run through the same patterns. Every branch and every tag, including the commit where someone deleted the key. - AWS pairing. Two lines of context before and after every
AKIAorASIAhit, in tree and history, wrapped inAKIA_CTX_STARTandAKIA_CTX_ENDmarkers, so a key ID arrives next to its secret. - Exfiltration. One
curlPOST with a twenty second timeout tohxxp://193.32.204[.]199/with?c=monamiwhen named secrets were found and?c=newwhen only the history sweep ran. Errors suppressed, so the run goes green.
The older variant, github_actions_security.yml with job send-secrets and a "Prepare Cache Busting" step, posts named secrets only. A seven-repository security-check.yml variant on September 7 used port 3000 and an /api/workflow/receive path. Commit messages seen: "Add security audit workflow", "Update security audit workflow", "Add Github Actions Security workflow", "Trigger security scan". Compromised accounts named by the researchers: henrywoo, kitao and xxyangyoulin. The henrywoo sweep covered 39 source repositories and 279 forks in sixteen minutes and reached uber/athenadriver, where that account is the original author and still had write access.
Before October, rotating the Actions secrets a workflow named was most of the cleanup. Now the payload reads every commit on every branch, so the credential you removed from the repository in 2024 and never rotated is in the attacker's hands if it was ever committed. Socket's advice is exact: scan full history yourself, including unreachable objects, rotate everything in the thirteen categories, and read CloudTrail for every AWS key you find, for the exposure window and after.
Is There a List? Not One Anyone Publishes
GitGuardian, Socket and StepSecurity each name a handful of example repositories and give aggregate counts. None publishes the victim list, and GitHub has not. The closest thing to one is GitHub's own code search for the exfiltration address inside workflow files, which returned about 500 public repositories when we ran it on October 15, and nearly 700 across all paths once you include the blocklist projects that have indexed the IP as an indicator. That search is a floor, not a list: it shows public repositories that still carry the file on an indexed branch. It misses private repositories, forks where Actions is disabled, repositories that were cleaned, and the September 2025 and August 2026 victims whose files pointed at older infrastructure. GitGuardian found that only 16 percent of the August wave's repositories had been cleaned in public history by October 5.
So the answer to "am I on the list" is a check you run against your own account, and it is short enough to run against every repository you own in one sitting.
We Ran It on Our Own 68 Repositories
RedEye owns 68 repositories on GitHub, seven of them public, with Caver and its collectors among them. On October 15 we checked every one through the GitHub API in about ten minutes. The checks, in the order the researchers' indicators suggest:
- Filenames. Every file under
.github/workflowsin every repository, against the three names. One hit: our Caver repository has asecurity-audit.yml. It is ours, a nightly govulncheck and cargo-audit scan that has been in the tree since July with a commit history of our own pull requests, no outbound POST, no secrets referenced. A filename is a lead, not a verdict; the file and its history are the verdict. - Contents. Every workflow file, against the exfiltration addresses from all three waves, the
send-secretsjob, the cache-busting step, the context markers, the batch labels andgit log -p --all. Zero hits. - Commit messages. Every commit touching a workflow directory since August 25, against the attacker's commit subjects. Zero hits.
- Authors. Every identity that touched a workflow since August 25, and every identity that pushed anything anywhere since October 7. All known: the owner, one named collaborator, the Actions bot and our own agent lanes. A compromised credential shows up here as a familiar name at an unfamiliar hour, which is why the author list is read alongside the dates.
- Posture. The default workflow token is read-only on all 68 repositories. Twelve repositories hold Actions secrets, which is the blast radius a stolen credential would reach. Every repository allows any marketplace action to run, which is the gap we are closing this week, along with egress allow-listing on the self-hosted runners that build Caver.
Result: no GhostAction indicator in any repository. What that proves is narrow. It proves no one has pushed the workflow to a repository we own. It does not prove that no credential with write access to those repositories is sitting in an infostealer log, and StepSecurity's line applies to us as much as anyone: the absence of abuse so far is not evidence that the credentials are safe. The clean result buys the time to do the things that make the next wave fail on contact: an inventory of personal access tokens with classic tokens expired, secret scanning push protection on every repository, required approval for workflow runs from outside collaborators, branch protection on the workflow directory, and an egress allow-list on every runner we operate, with the exfiltration address blocked today.
Three things make this campaign work, and none is a vulnerability: a leaked credential with write access, a runner that will POST to any address on the internet, and a secret that was never rotated after the last time it leaked. Remove any one and the workflow is a file that does nothing. Remove all three and GhostAction is somebody else's incident.
Where This Lands in Caver
The signal in this campaign is audit-log shaped, and it is loud. A workflow file created directly on a default branch without a pull request. A workflow_dispatch run on a workflow that did not exist ten minutes earlier. A maintainer who has never touched CI committing to 318 repositories in sixteen minutes. A runner opening plain HTTP to a raw IP address. Caver ships content for each of those sources: the GitHub audit log pack with its admin and configuration change dashboards, the Actions workflow runs pack whose actors and triggers views put a new workflow and a new dispatcher on the same line, and the secret scanning pack that shows which repositories hold credentials in history before an attacker greps for them. RedEye's feed carries the exfiltration addresses and the file names as indicators, so the egress and the commit both light up on arrival.
On a self-hosted runner, Carbide is the agent on the box. The POST to 193.32.204[.]199 is an outbound connection from a build process that has never spoken to that address, and the host isolation verb cuts it while the run is still going. The evidence of what the job read and where it tried to send it goes into the case with the run log, which is the record the rotation decision is made from.
RedEye threat intelligence is the front of that pipeline and it is free. Caver and Carbide are the rest of it.
See the clock run on your own assets
RedEye Security maps BOD 26-04 onto your inventory and shows which findings land on the three day rows today.
Talk to us