Skip to content
Security

Gheist GitHub Attack: What I'd Check Before the Next Deploy

The Gheist GitHub attack uses stolen tokens to expose Actions secrets. I'd check workflow history, cloud access and approval gates before trusting the next deploy.

Topic
Security
Reading time
6 min
Length
1,393 words
Published
Oct 26, 2026
03:06 pm IST
In this article
  1. Why I’d treat repository write access as secret access
  2. Did GitHub’s public-repository protection stop Gheist?
  3. Checking repositories for Gheist workflows
  4. Start with remote branches
  5. Correlate Actions and audit evidence
  6. Follow the credentials into the cloud
  7. Include self-hosted runners
  8. Containing Gheist and narrowing Actions access
  9. What Gheist hardening does not solve

The Gheist GitHub attack uses already-stolen tokens to plant workflows that expose Actions secrets, retrieve the logs through GitHub’s API, and delete the runs. The supplied ByteMuni report, citing Wiz, describes more than 13,500 planted branches across more than 850 compromised accounts. I would treat this as a reason to review repository access and deployment credentials, not as a GitHub vulnerability waiting for a patch.

What catches my attention is how ordinary the mechanism is. A branch, a workflow file, a push event, and a log download. I would not expect a review focused only on application dependencies or outbound attacker domains to cover this path.

Why I’d treat repository write access as secret access

The report quotes GitHub’s documentation: any user with write access to a repository has read access to the secrets configured in it. That is the permission boundary I would start with. If I let a token write workflows, I should not assume the secrets available to those workflows remain separate from that token.

According to the report, Gheist creates a branch beginning with ci-sync-, adds .github/workflows/sync-check.yml, and uses the commit message ci: sync config. The workflow runs on push and prints the environment and available secrets encoded in base32. The attacker downloads the log and deletes the run seconds later.

I would pay particular attention to two misleading signs of safety. First, log masking does not reliably hide transformed secrets. The report explains that base32 output no longer matches the original secret value. Second, permissions: {} limits the job’s automatic GITHUB_TOKEN; it does not remove access to repository secrets. I would keep restrictive permissions, but not mistake them for a secret-access policy.

In the newsroom tools I work on, I would start with repositories whose workflows can publish or deploy. My concern would not stop at the application code. I would want to know which credentials a newly pushed workflow could reach before anyone reviewed it.

Did GitHub’s public-repository protection stop Gheist?

For the public-repository runs Wiz checked, yes: the report says they were held for approval and the payload did not execute. GitHub introduced that safeguard on July 28, 2026, for workflows it identifies as potentially malicious.

But the documented scope matters. The report says the hold applies to public repositories on github.com, not private repositories or GitHub Enterprise Server. Wiz found evidence of completed and deleted runs in those unprotected settings. I would therefore put private deployment repositories near the front of my review, rather than assuming private means safer here.

I would not turn the public-repository finding into a blanket assurance either. The hold depends on GitHub flagging the run. I would leave suspicious runs unapproved and still investigate the token that created them.

Checking repositories for Gheist workflows

I would separate hunting from cleanup. First I would record the suspicious branch, commit, workflow and available audit evidence. Then I would work through containment. Deleting the visible branch is not evidence that its credentials were never read.

Start with remote branches

For a repository I already have cloned, I would use the source’s read-only check:

git ls-remote --heads origin | grep -E 'refs/heads/ci-sync-[0-9a-z]{6}$'

I would run it against the intended repository remote and inspect any match without executing its code. The reported pattern is a six-character lowercase alphanumeric suffix. The matching commit should add the workflow file with the message described above. A branch name alone is a lead, not my entire incident assessment.

I would not stop after an empty result. The source explicitly warns that branches may have been deleted or removed through other account activity. For an organisation-wide check, I would use the report’s GitHub CLI approach and verify that the repository inventory covers the repositories I actually intend to investigate.

Correlate Actions and audit evidence

Next I would look for activity using the gheist user agent and runs on ci-sync- branches that completed and were deleted within a minute. I would compare those events with workflow-file changes and the account credited with the commit.

I would treat attribution to that account as a starting point for token investigation, not proof that its owner performed the action. The campaign uses stolen tokens, and the report says its commits appear under the token owner’s identity.

Follow the credentials into the cloud

If the repository uses OIDC, I would inspect cloud audit records for role assumptions associated with suspicious branches. The source explains that, without a deployment environment, GitHub’s subject claim includes the branch reference. Its AWS hunting example searches AssumeRoleWithWebIdentity events for the branch pattern.

I would check each relevant AWS region and use retained CloudTrail or SIEM history where needed. The supplied guidance notes that lookup-events covers only the last 90 days of management events. I would also check which subject format the workflow uses before interpreting a missing branch-name match as reassuring.

Include self-hosted runners

The report describes a later job named sync-host that attempts broader collection from self-hosted machines. Its indicators include .gdmp_pat, .gdmp_patg, .gdmp_sweep and gdmp-pivot. I would search for those alongside the workflow evidence.

I would preserve the uncertainty here: Wiz described that job as buggy and reported no successful run in its analysis. That is not a demonstrated host takeover. Still, following the source’s response guidance, I would treat a runner and its cloud instance role as compromised if the malicious branch ran there.

Containing Gheist and narrowing Actions access

If I found evidence of execution, I would not make branch deletion my finish line. The source recommends rotating every secret the repository could use, including repository, organisation and environment secrets. I would build that inventory explicitly so that the response did not end with only the most obvious deployment key.

I would revoke the token that pushed the workflow and investigate the owner’s computer for credential-stealing malware. Replacing a token without addressing its theft would not be a response I trusted. I would also review subsequent cloud activity, especially secrets-manager access, rather than assuming the exposure stopped inside GitHub.

For prevention, my first choice would be production environment secrets with required reviewers. GitHub’s documentation, as quoted in the source, says a job cannot access those secrets until a reviewer approves it. I would make that approval meaningful: check the workflow and branch requesting access, rather than approve a familiar-looking job name.

For AWS OIDC, I would inspect the trust policy as carefully as the workflow. The source provides this condition fragment for a production environment:

{
  "Condition": {
    "StringEquals": {
      "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
      "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:environment:production"
    }
  }
}

This is a condition fragment, not a complete policy. I would substitute the actual organisation, repository and environment, pair it with required reviewers, and test the intended deployment path. I would avoid a broad subject such as repo:my-org/*, which the source warns against.

I would then review automation tokens. The report recommends GitHub Apps for automation and short-lived, fine-grained tokens limited to specific repositories where tokens are necessary. My priority would be removing unnecessary reach, not merely replacing one broadly privileged credential with another.

What Gheist hardening does not solve

I would not sell OIDC as a complete answer. A trust policy that accepts an attacker-controlled branch still leaves a route to cloud access. My preference would be narrowly scoped trust plus reviewed production environments, with tests that legitimate releases still work.

That choice adds an approval step. For a newsroom publishing workflow, I would want that friction placed deliberately: protecting production credentials without casually blocking unrelated editorial work. I would test the release path before making approval mandatory across every job.

I would also separate environment protection from runner protection. Moving production secrets behind reviewers does not constitute a review of files, process environments, Docker access or instance credentials on a self-hosted machine. The source recommends ephemeral runners, no Docker socket access and restrictions on cloud metadata access. I would assess those controls independently.

If a team does not use GitHub Actions, I would skip this specific workflow hunt and focus on whether its GitHub tokens were exposed. If it uses only public repositories, I would still review suspicious activity, but prioritise repositories with production secrets and cloud trust.

My next step would be a controlled access review: list what a newly writable branch can reach, then compare that list with what I intended it to reach. I would want that answer before trusting a quiet Actions page.

Deepak Kumar

Written by

Deepak Kumar

Sr Software Engineer at India Today Group | Aaj Tak · MERN Stack · Generative AI

I have shipped the boring security work — auth flows, token handling, dependency upgrades after a CVE lands on a Friday. I write here about what those systems actually do once real traffic hits them. Hiring a software developer in India? Here is how I work.

More on ByteMuni

ByteMuni is a developer publication: tutorials and source-checked tech news, published daily.

Read more on ByteMuni →
Message me