GhostAction: 1,900 hijacked GitHub accounts, 30,000 repositories, and a workflow called "Security Audit"
Attackers logged into developers' own GitHub accounts and committed a fake security workflow that dumped CI/CD secrets and scanned years of git history for cloud and AI keys. No vulnerability in GitHub was needed. One GitHub setting quietly stopped most of it from running.
Background
GitHub Actions lets a repository run automated jobs — builds, tests, deployments — whenever code is pushed. Those jobs routinely hold secrets: cloud access keys, package-registry tokens, API keys for AI providers. Anyone who can commit a workflow file to a repository can, in principle, make those jobs do something else with those secrets.
GhostAction was first documented by GitGuardian in September 2025, when it stole 3,325 secrets across 817 repositories. It never fully stopped. In 2026 it came back in waves, each larger than the last, culminating in a burst on October 8–9 that touched more than 30,000 repositories.
From one leaked token to secrets on an attacker's server
What actually happened
From August 31, 2026, GitGuardian observed a malicious workflow being pushed to public repositories — 772 of them across 373 users and organizations by September 30. The commits were made under the victims' own GitHub identities. The workflow, named security-audit.yml or github_actions_security.yml, was configured to run on every push and on manual trigger. It read the repository's GitHub Actions secrets by name (the operator first extracted which secret names each repository used and hardcoded them into the payload), checked out the full git history, scanned the working tree and every past commit for credential patterns — AWS keys, GitHub and GitLab tokens, Google and Firebase keys, and Anthropic, OpenAI and OpenRouter API keys — and sent what it found in a single plain HTTP POST to an attacker-controlled server.
Across those 772 repositories, the workflows targeted 2,577 secrets. But GitHub held most workflow runs for approval. Of 3,669 runs GitGuardian collected across 605 repositories, only 499 actually executed, in 32 repositories, and 336 completed — exfiltrating 26 secrets from 13 repositories. By October 5, only 124 of the 772 repositories (16%) had been effectively cleaned; in 92 cases the attacker simply edited a malicious workflow left behind by an earlier wave.
Then the campaign escalated. On October 8, the account of Takashi Kitao, author of the 18,400-star pyxel game engine, pushed the workflow to 27 repositories starting at 13:20 UTC. Eight hours later, the account of Henry Wu, original author of Uber's athenadriver, pushed it to 318 repositories in sixteen minutes — under three seconds per repository. Within the same window the payload went to 160 previously hit victims and then, twenty minutes later, to about 28,000 new repositories. GitGuardian's tally of the October burst: more than 30,000 repositories across roughly 3,000 users and organizations, about 1,900 compromised accounts and 3,174 targeted secrets. GitHub began blocking the workflow from running on October 9; further waves with the same payload followed on October 10 and 12.
Every run also reported the repository's identity back to the operator, whether or not it found credentials — giving the attacker a running map of repositories where their code executes. Private forks and downstream mirrors carrying the workflow remain the most exposed, because private repositories are where committed credentials tend to live.
Root cause
- Attackers used valid, compromised GitHub account credentials to commit malicious workflow files directly to victims' repositories under the victims' own identities.
- No vulnerability in GitHub Actions was involved; the attack relied on normal Actions behavior — workflows run on push and can read the repository's secrets.
- Long-lived secrets stored as Actions secrets, and credentials committed anywhere in git history, gave the workflow something worth stealing.
- Most affected repositories were not cleaned after earlier waves, allowing the attacker to re-use 92 previously planted workflows.
- How the ~1,900 accounts were first compromised has not been confirmed. Researchers at StepSecurity and others consider leaked personal access tokens from infostealer logs or credential dumps the most likely source; Socket says it did not observe the method.
- The identity of the operator is unknown. GitGuardian links the 2026 waves to the 2025 GhostAction campaign by workflow and technique.
Timeline
Detection
Detected by third-party researchers, not by the affected developers: GitGuardian (tracking the campaign since 2025), StepSecurity and Socket identified the malicious workflow commits and published analyses. GitHub then blocked the workflow.
About 5 weeks for the Aug 31 wave to be published; the Oct 8 burst was flagged within a day
- A new workflow file appearing on the default branch, committed directly rather than through a pull request.
- Hundreds of repositories modified from one account within minutes — one every few seconds — a pattern no human produces.
- Workflow runs waiting for approval that nobody on the team had expected.
What to monitor for in your own environment
Any change to files under .github/workflows/, especially by direct push to the default branch
GitHub audit log / webhookWorkflows named security-audit.yml or github_actions_security.yml, or using checkout with fetch-depth: 0 plus a curl POST
Repository code searchBurst of commits across many repositories from one identity in a short window
GitHub audit logOutbound HTTP requests from CI runners to unknown IP addresses
CI runner network egress logsUse of a cloud or AI key from an IP or region it has never been used from before
Cloud audit logs (CloudTrail, GCP Audit Logs)Containment, eradication & recovery
Containment
Oct 9, 2026 onward- GitHub began blocking the malicious workflow from running.
- Researchers published indicators and search queries so maintainers could find the workflow in their repositories.
- Recommended: revoke the compromised GitHub credential that pushed the workflow.
Eradication
- Delete the malicious workflow from every branch, not just the default branch.
- Check forks and downstream mirrors, which carry the workflow independently of the original repository.
- Remove secrets committed anywhere in git history, not only the current tree.
Recovery
- Rotate every secret the workflow could read — Actions secrets and credentials found in history — prioritizing cloud keys, registry tokens and AI API keys.
- Review cloud and AI-provider logs for use of those keys since August 31.
- Only 16% of earlier-wave repositories were effectively cleaned within weeks — recovery is where this campaign keeps winning.
Security control analysis
About 1,900 accounts' credentials were usable by an attacker, most likely leaked personal access tokens.
Workflow files reached the default branch directly, without a pull request or review.
GitHub held most runs for approval: of 3,669 runs, only 499 executed and 336 completed.
Static cloud and AI keys in Actions secrets and committed history gave the workflow real credentials to steal.
Runners could POST secrets over plain HTTP to an arbitrary IP address.
84% of affected repositories from the August–September wave were still not cleaned by October 5.
Controls that would have prevented or limited this
A leaked token expires quickly and cannot push workflows to every repository the user can reach.
A malicious workflow would sit in a pull request instead of running on the next push.
There is no long-lived cloud key in Actions secrets for the workflow to dump.
The single curl POST to the attacker's IP fails, even if the workflow runs.
Most runs stay blocked, and any that do run find nothing reusable in git history.
Blast radius
What the campaign reached
- 30,000+ repositories across about 3,000 users and organizations (Oct 8–9 burst)
- About 1,900 developer accounts used to commit the workflow
- 3,174 secrets targeted in the October burst; 2,577 in the Aug–Sept wave
- High-profile projects including pyxel and Uber's athenadriver
What held
- Most workflow runs held for approval — 26 secrets confirmed stolen from the Aug–Sept wave, not 2,577
- GitHub blocked the workflow from running from October 9
- No vulnerability in GitHub Actions itself
How GitHub's approval gate thinned the August–September wave
What they got right
GitHub's run-approval requirement measurably limited the damage — the clearest evidence in this incident that platform defaults matter.
Security researchers at GitGuardian, StepSecurity and Socket tracked the campaign continuously and published workflow names, payload shape and search queries, so maintainers could check their own repositories.
GitHub moved to block the specific workflow from running on October 9, within a day of the largest burst.
Why this keeps happening
Personal access tokens leak constantly — into infostealer logs, public repos, CI output — and many are long-lived with broad repository access.
Workflow files are code that runs with access to secrets, but most teams don't review changes to them as carefully as application code.
Cleanup is incomplete: when only 16% of affected repositories are cleaned, attackers simply return to the ones still carrying their workflow.
Lessons for your own environment
- A developer token is a key to your pipeline, not just your code
With a stolen token, an attacker can commit a workflow that runs with your secrets. Treat tokens as privileged credentials: short-lived, scoped, monitored.
- Review workflow changes like production code
The attack lived entirely in .github/workflows. CODEOWNERS and PR review on that directory turn a silent compromise into a visible diff.
- Don't store what you can federate
OIDC workload identity means there are no long-lived cloud keys sitting in Actions secrets for a workflow to dump.
- Your git history is a credentials archive
The payload scanned every past commit. A key removed from the current code but still in history is still exposed.
- Keep platform guardrails on
Workflow-run approval stopped most of this campaign. It is worth the friction.
- Finish the cleanup — every branch, every fork, every secret
Attackers re-used 92 workflows victims never removed. Incomplete recovery invites the next wave.
CISO & board lessons
- Ask engineering for the number of active classic or long-lived personal access tokens with broad repository access. That number is your exposure to the next GhostAction wave.
- Make OIDC federation the default for CI-to-cloud authentication, and set a deadline for retiring stored cloud keys in CI secrets.
- Require CODEOWNERS review for workflow directories across the organization, and keep GitHub's workflow-approval settings at their protective defaults.
- Treat a supply-chain alert as a rotation event, not a deletion event: deleting the workflow does nothing for secrets that already left.
- Track cleanup to completion with a metric — percentage of affected repositories, branches and forks verified clean — rather than closing the ticket when the first fix lands.
Action plan
First 24 hours
- Search all repositories, branches and forks for security-audit.yml, github_actions_security.yml and similar recent workflow additions.
- Revoke the GitHub credential that committed each malicious workflow.
- Rotate every Actions secret in affected repositories, starting with cloud keys and package-registry tokens.
First 7 days
- Scan full git history for committed credentials and rotate anything found; purge from history where feasible.
- Review cloud, registry and AI-provider logs for use of exposed keys since August 31.
- Enable branch protection and CODEOWNERS on .github/workflows for all active repositories.
First 30 days
- Migrate CI-to-cloud authentication to OIDC federation and delete stored cloud keys.
- Replace broad classic tokens with fine-grained, expiring tokens; enforce phishing-resistant MFA for maintainers.
- Restrict CI runner egress and add alerting on workflow-file changes and unexpected run approvals.
Could this happen in your organization?
- Would a direct push of a new workflow file to your default branch be blocked, reviewed or at least alerted on?
- How many long-lived cloud or AI API keys are stored as CI secrets today?
- Have you scanned the full git history of your repositories for credentials, not just the current code?
- Can your CI runners make outbound HTTP requests to any IP on the internet?
- Do your developers use fine-grained, expiring tokens, and would you know if one appeared in an infostealer log?
- If you were hit in an earlier wave, can you prove every branch and fork has been cleaned?
If this happened to you: what to ask, and what to say
Knowing the lesson isn’t the same as knowing what to do with it Monday morning. A security lead, a CISO, and a customer-facing team each need something different from this incident.
- "Search every repo and fork for unexpected workflow files added since August 31 — what did we find?"Ask for the query used and the count, not a reassurance.
- "Which of our CI secrets are long-lived cloud keys that could be OIDC instead?"Every static key is a candidate for the next dump.
- "Who can push directly to default branches, and do workflow changes need review?"GhostAction needed neither a PR nor a reviewer.
- Explain it without jargon.Supply chain attacks sound abstract; this one isn't."Attackers used stolen developer logins to add a fake 'security audit' job to code repositories. That job tried to copy the passwords our build systems use to reach the cloud."
- Be clear about what's been rotated.Rotation, not deletion, is the meaningful milestone."We've removed the malicious job and rotated every credential it could have read. We are now replacing stored cloud keys with short-lived credentials so there is nothing to steal next time."
- If you publish open-source or SDKs, tell downstream users plainly.Your users may have pulled a compromised fork."A malicious workflow was added to some of our public repositories using a compromised maintainer account. Released packages were not modified. If you forked these repositories, please delete any security-audit.yml workflow and rotate secrets in your fork."
References & confidence
- ConfirmedGitGuardian — GhostAction returns (Oct 2026): 772 repos, 2,577 secrets targeted, 26 exfiltrated, 16% cleaned
- ConfirmedThe Hacker News — GhostAction compromises about 1,900 GitHub accounts, targets over 30,000 repositories (Oct 15, 2026)
- ConfirmedThe Hacker News — Credential-stealing GitHub Actions workflows planted in tens of thousands of repositories (Oct 9, 2026) — Cites Socket's count of 500+ accounts since Oct 7.
- ConfirmedStepSecurity — GhostAction returns: workflows now mine credentials from entire git histories (Oct 9, 2026) — Source for the pyxel and athenadriver account timelines and payload shape.
- ConfirmedThe New Stack — Hackers hijacked 1,900 GitHub accounts. Then they went after 30,000 repos.
- ReportedInitial account compromise via leaked personal access tokens — Most likely vector per StepSecurity and others; Socket did not observe the method. Not confirmed.