· via dev.to (home feed)
GhostAction campaign steals CI secrets via fake GitHub Actions security workflows
A campaign tracked as GhostAction is using compromised maintainer accounts to inject fake security-audit GitHub Actions workflows, harvesting cloud, AI and API keys from CI runners and full git history.

What happened
Since October 7, a campaign that Socket tracks as GhostAction has been inserting malicious GitHub Actions workflow files into legitimate repositories through compromised maintainer accounts. According to a dev.to write-up of the incident, which cites all three research teams, GitGuardian has counted a second wave touching more than 772 additional repositories, and StepSecurity puts the number of stolen secrets at over 3,000.
The framing matters: this is not a GitHub zero-day or a privilege escalation. The attackers abused automation that repository owners already trust — a workflow file that looks unremarkable while sweeping up whatever the CI can see.
How the attack works
A compromised maintainer account commits a file named .github/workflows/security-audit.yml or .github/workflows/github_actions_security.yml, with a commit message reading "Add security audit workflow". Because the commit comes from a real account, the workflow runs inside the repository's own CI, with its secrets in scope.
The workflow checks out the repository with fetch-depth: 0 and walks git log -p --all, which means secrets that were committed and deleted years ago are still readable. The post says harvested values include AWS keys with a couple of lines of surrounding context, Anthropic, OpenAI and OpenRouter keys, GitHub, GitLab and Google API tokens, and Slack, SendGrid and PyPI credentials. Everything is sent in cleartext over plain HTTP to a single attacker IP, which the post identifies as 193.32.204.199. Plaintext egress to one fixed address is a convenient detection signal for defenders.
The 15-minute self-audit
The post orders the checks this way:
- Look for injected workflow files. Run
git log --diff-filter=A --name-only --format=%ci -- .github/workflows/security-audit.yml .github/workflows/github_actions_security.ymland treat any file added on or after October 7 that no teammate can account for as compromised. - Walk the Actions run history for runs that cannot be tied to your team, and archive the logs before deleting anything, since those logs are what you will need to investigate later.
- Rotate credentials: cloud keys, personal access tokens, PyPI and npm tokens, AI provider keys. The critical nuance is that rotating today's secrets does nothing for values leaked from history; anything ever committed and never revoked still needs revoking.
- Scan the full history, not just the current checkout, with
gitleaks git .or TruffleHog. A clean working tree says nothing about older commits. - Search network telemetry for past connections to the exfiltration IP, then block it.
The structural lesson
CI runners are built with access to the repository's secrets, so any repository where a pull_request-triggered workflow gets shell access to secrets, or where maintainer commits land directly on the default branch, has the same exposure GhostAction exploited. The fixes the post recommends are inexpensive: set minimal permissions per workflow instead of organisation-wide write defaults, require review before commits reach the default branch, keep secrets away from fork-triggered runs, and never interpolate secrets into run: strings where pull-request-controlled code could echo them back. That last point is a quieter variant of the same problem: secrets do not need to be exfiltrated by a campaign if fork code can print them from inside the runner.
Why it matters
GhostAction shows how little an attacker needs when the target's trust model is generous: no exploit, no malware payload, just a dull-looking YAML file committed by a real account. The consequences reach beyond currently configured secrets, because the history-walking step pulls in credentials deleted long ago. For anyone running GitHub Actions, the audit is short, and the hardening steps — least-privilege workflow permissions, branch protection, tighter secret scoping — would have blunted this campaign from the start.
- #github-actions
- #ci-cd
- #security
- #supply-chain
- #secrets