What Happened
A threat actor named Gheist compromised over 850 GitHub accounts and planted malicious GitHub Actions workflows across more than 13,500 branches. The attack targeted repository and environment secrets by encoding them to bypass GitHub's native secret masking, then exfiltrating the decoded values through GitHub's API. This campaign exploited the trust organizations place in their CI/CD automation, turning GitHub Actions into a tool for extracting credentials, API keys, and tokens.
Timeline
The exact start date of the Gheist campaign isn't public, but Wiz Research documented the active phase:
- Discovery: Wiz Research identified the malicious workflow pattern across hundreds of repositories.
- Scale confirmation: Investigation revealed over 13,500 malicious branches spanning more than 850 compromised accounts.
- Current status: GitHub has implemented a control requiring collaborator approval for workflow runs in public repositories, but private repositories remain vulnerable to the same technique.
The attack continues to affect organizations that haven't identified and removed the malicious workflows from their repositories.
Which Controls Failed or Were Missing
Credential compromise detection: The initial account compromises went undetected. Your team didn't have monitoring in place to flag unusual authentication patterns or new device logins to developer accounts.
Workflow approval requirements: GitHub's default configuration allows workflows to run automatically without security review. The new control requiring collaborator approval only applies to public repositories. Your private repositories, which likely contain your most sensitive secrets, still auto-execute workflows.
Secret masking bypass: GitHub's native secret masking relies on pattern matching. Gheist encoded secrets using base64 or similar transforms, then decoded them in the workflow. The masking system never saw the plaintext value leave the environment. This isn't a GitHub bug. It's a fundamental limitation of output-based masking.
API-based exfiltration: The malicious workflows used GitHub's API to send data. Your network monitoring probably allows GitHub API traffic by default. You can't distinguish legitimate CI/CD operations from credential theft without inspecting the actual API calls.
Branch protection gaps: The attacker created thousands of branches without triggering alerts. Your branch protection rules likely focus on main or production branches, not on the long tail of feature branches where these workflows hide.
What the Standards Require
NIST 800-53 Rev 5 addresses this scenario through multiple controls:
AC-2 (Account Management): You must review accounts with elevated privileges. Developer accounts that can modify workflows qualify. The control requires you to detect compromised accounts before they're used to plant malicious code.
AU-6 (Audit Review, Analysis, and Reporting): You need automated mechanisms to review audit records for indications of inappropriate or unusual activity. A single account creating hundreds of branches with workflow modifications meets that threshold.
CM-3 (Configuration Change Control): Changes to your CI/CD configuration, including workflow files, require documented approval. If you're auto-executing workflows without review, you're not meeting this requirement.
PCI DSS v4.0.1 Requirement 6.3.2 states that security vulnerabilities are identified and addressed. If you're storing payment card data and your CI/CD pipeline can access it, a workflow that exfiltrates secrets is a direct path to cardholder data. You need to treat workflow modifications as code changes subject to security review.
SOC 2 Type II Common Criteria CC6.6 requires logical access controls to protect against threats from sources outside its system boundaries. GitHub Actions workflows that can access your secrets without approval fail this control. Your auditor will ask how you prevent unauthorized workflow execution.
Lessons and Action Items for Your Team
Require approval for all workflow runs: Don't wait for GitHub to extend the public repository control. Implement your own approval gate using branch protection rules and required reviewers for any changes to .github/workflows/. This stops the attack at the workflow modification stage.
Audit your secrets right now: Run this search across your organization: path:.github/workflows/ secrets. Review every workflow that accesses secrets. Look for encoding functions (base64, hex, URL encoding) near secret references. If you find echo "${{ secrets.API_KEY }}" | base64, you've found the pattern.
Monitor GitHub API calls from Actions: Your SIEM should ingest GitHub audit logs. Create alerts for API calls from workflow runs that target external endpoints. The legitimate use case is rare enough that you can review each instance.
Implement secret rotation triggers: When you detect a compromised workflow, you need to rotate every secret it could have accessed. Document which workflows touch which secrets now, before the incident. Map your secrets to rotation procedures. You can't respond quickly without this preparation.
Separate CI/CD secrets by environment: Don't give your build workflows access to production secrets. If your test environment workflows can read production database credentials, you've expanded your attack surface unnecessarily. Use GitHub's environment protection rules to require approval before workflows can access production secrets.
Enable branch protection on all branches: The default approach of protecting only main branches doesn't work when attackers create thousands of feature branches. Require pull request reviews for all branches, or implement a naming convention that auto-applies protection rules.
Review compromised account recovery: If an attacker gains access to a developer account, what's your process? You need to revoke sessions, rotate any secrets the account could access, and audit all recent actions. The Gheist campaign shows that attackers will modify workflows immediately after compromise. Your incident response time needs to be faster than their dwell time.
The Gheist campaign isn't sophisticated. It's effective because it exploits the gap between how you think about CI/CD security and how attackers actually use your automation tools. Your workflows have the same access as your most privileged service accounts, but you're probably not monitoring them with the same rigor. Fix that gap this week.





