The short version: GhostAction is a GitHub Actions credential-theft campaign that GitGuardian first documented in September 2025, when it had compromised 817 public repositories and exfiltrated at least 3,325 secrets. In early October 2026 the campaign returned with a new payload and a much larger blast radius: about 1,900 compromised GitHub accounts were used to push a workflow called security-audit.yml into more than 30,000 repositories across roughly 3,000 users and organizations, attempting to extract 3,174 secrets in a single 24-hour window. The new workflow doesn't just read GitHub Actions secrets anymore — it checks out a repository's complete commit history and runs git log -p --all against it, hunting for Anthropic, OpenAI, OpenRouter, AWS, and package-registry credentials that were ever typed into a file, even ones deleted years ago. The campaign is still active, and researchers at Socket, StepSecurity, GitGuardian, and The Hacker News published new findings throughout October.
What happened
GhostAction isn't new. GitGuardian's original disclosure found that the campaign compromised 817 public repositories across 327 GitHub users and exfiltrated at least 3,325 secrets, using stolen maintainer credentials to push a malicious GitHub Actions workflow disguised as a routine security check. A second wave between August 31 and September 30, 2026 hit 772 public repositories belonging to 373 GitHub users and organizations, according to GitGuardian's tracking of the campaign.
The wave that matters this week started on October 8, 2026. StepSecurity and Socket both tracked two compromised maintainer accounts — one belonging to Takashi Kitao, author of the 18,400-star pyxel game engine, and a second account, henrywoo, which retained write access to Uber's own uber/athenadriver repository. In two automated pushes lasting minutes, the attackers committed a file named .github/workflows/security-audit.yml to 345–346 repositories, with commit messages as mundane as "Add security audit workflow."
By October 15, The Hacker News reported that GitGuardian had tied the October 8–9 activity to a far larger footprint: more than 30,000 repositories across roughly 3,000 users and organizations, reached by compromising about 1,900 GitHub accounts, with attackers attempting to extract 3,174 secrets from public repositories' CI in that window alone. That is a roughly 37x jump in repository count from the original 2025 disclosure, inside a single campaign.
1 · September 2025 — Original disclosure
GitGuardian names the campaign GhostAction after finding it had hit 817 public repositories across 327 users, exfiltrating at least 3,325 secrets via a fake security-check workflow pushed with stolen maintainer credentials.
2 · Aug 31–Sept 30, 2026 — Second wave
A follow-on wave compromises accounts belonging to 373 GitHub users and organizations and hits 772 public repositories, per GitGuardian's ongoing tracking.
3 · Oct 8, 2026 — The new payload appears
Compromised maintainer accounts for the pyxel game engine and Uber's athenadriver push security-audit.yml to 345–346 repositories in minutes. Unlike earlier waves, the workflow now scans full git history, and Socket confirms the runs executed successfully.
4 · Oct 8–9, 2026 — Scale explodes
GitGuardian ties the same push mechanics to over 30,000 repositories and roughly 3,000 accounts, with 3,174 secrets attempted in the window, as reported by The Hacker News on October 15.
5 · Oct 9–20, 2026 — Ongoing disclosure
Socket, StepSecurity, GitGuardian, GBHackers, and The Hacker News publish overlapping technical write-ups; as of Socket's October 9 check, the workflow file was still present on the default branch of affected repositories including uber/athenadriver and kitao/pyxel.
The technical shift: from CI variables to full git history
Earlier GhostAction waves stole exactly what the name "Actions secrets" implies: whatever a repository had declared as a named secret and exposed to a workflow. That's a known, bounded attack surface — if you never declared a secret, the old payload couldn't see it.
The October payload does something categorically different. It checks out the repository with fetch-depth: 0, which pulls the entire commit history instead of a shallow clone, and then runs git log -p --all against it — dumping every patch, on every branch, ever committed. According to GBHackers's analysis of the payload, it applies thirteen credential-matching patterns against both the working tree and that full history dump, covering AWS access keys and secret keys, Anthropic API keys, OpenAI API keys, OpenRouter API keys, GitHub and GitLab tokens, and Google, Slack, and SendGrid credentials, plus npm, PyPI, and crates.io publishing tokens.
Where the pattern match finds an AWS access key identifier, the workflow also captures the surrounding lines of text — an attempt to recover the matching secret access key, which developers often paste right next to the key ID. Everything collected — named Actions secrets, working-tree matches, and history matches — is bundled into a single cleartext HTTP POST sent to a hardcoded IP address, 193.32.204[.]199, rather than a domain name, which several researchers noted sidesteps DNS-based blocking.
Socket also found a meaningful behavioral change: in the original wave, most injected workflow runs stalled waiting on manual approval before executing. In the October wave, the runs executed on their own and the collection server acknowledged receipt — in other words, this time the exfiltration largely succeeded rather than being caught in GitHub's approval gate.
Why a "briefly committed" secret is not a briefly exposed one
The practical lesson here isn't new in theory, but GhostAction makes it concrete at scale: a credential that was ever typed into a file and committed — even if the very next commit deleted it — is still sitting in the repository's object database, reachable by anyone who can run git log -p --all. Deleting the line from the current file removes it from the working tree. It does not remove it from history. Rewriting history with tools like git filter-repo or BFG can scrub old commits from a repo going forward, but it does nothing to a credential that's already been copied out by an attacker, and it doesn't retroactively protect forks, clones, or cached copies made before the rewrite.
This is why treating "it's in a CI variable" and "it was committed once, three years ago, and then deleted" as different risk tiers stops making sense once an attacker has a workflow that can crawl the whole history automatically. Both are just locations where a plaintext credential sits, waiting to be read by something with repository access. GhostAction's October payload collapses the distinction on purpose.
Why Anthropic, OpenAI, and OpenRouter keys specifically
The inclusion of AI-provider key patterns alongside AWS and package-registry tokens reflects where developer habits have drifted. API keys for Anthropic, OpenAI, and OpenRouter get pasted into .env files, test scripts, and notebook cells constantly during normal development — often with the intention of removing them before a commit, and often not quite managing it. A regex that matches sk-ant- or sk-proj- prefixes across an entire git log will find those slip-ups regardless of how careful the team has been with their current main branch.
Cloud and CI credentials carry obvious blast radius — an AWS key can mean compute, storage, and data access. AI provider keys carry a different but increasingly expensive risk: unmetered usage against billed, rate-limited model endpoints, plus whatever downstream data those keys can reach through connected tools or agents.
What this means for credentials your process never holds
There's an architectural point worth being precise about here, because it's easy to overstate. GhostAction's history-mining payload can only exfiltrate a credential that exists somewhere it can read: a GitHub Actions secret, a file in the working tree, or a patch in git history. If a third-party API key is never written to any of those places — because it's injected at the network edge by a gateway at request time, rather than loaded into the application's environment or a CI variable — then there is nothing for git log -p --all to find, no matter how far back it searches. That's the model behind KnoxCall's AI gateway approach: the application process, the CI runner, and any AI agent calling out to Anthropic, OpenAI, or another provider never hold the real key at all, so it can't leak through a committed .env file, a build log, or a dependency's malicious postinstall script.
To be clear about the limits of that architecture: it addresses the specific failure mode of a credential sitting in a file, variable, or history where an attacker with repository or CI access can read it. It does not stop an attacker from compromising a maintainer's GitHub account in the first place, and it doesn't make AWS infrastructure keys or npm/PyPI publishing tokens disappear if your team still needs standing credentials for those systems. GhostAction's account-takeover vector and its targeting of package-registry tokens are a different problem that requires rotating and scoping long-lived personal access tokens, not just moving API keys off the wire.
git log -p --all, it is not a secret anymore — regardless of when it was deleted, and regardless of whether it was ever in a CI variable to begin with.What to do if you maintain a public GitHub repository
- Search your repositories' default branches for
security-audit.yml,security-check.yml, orgithub_actions_security.ymlworkflow files you did not add yourself. - Check Actions run logs for any execution of those workflows, and treat every secret available to that workflow — not just ones you can confirm were sent — as compromised.
- Rotate CI/CD secrets, cloud keys, package-registry tokens, and AI provider keys that the affected repository's workflows could reach, including ones pulled from org-level secret stores.
- Audit git history for credentials committed and later deleted — tools like gitleaks or trufflehog can scan history, not just the current tree — and rotate anything they find, since removal from history doesn't revoke the key itself.
- Review personal access token scopes and expirations for maintainer accounts; a broadly-scoped, long-lived PAT is the entry point this campaign depends on.
For a broader framework on reducing how many places a credential can leak from in the first place, see our guides on API security fundamentals and comparing gateway and secrets-management approaches.