Scope: any GitHub Personal Access Token (PAT), gh CLI session, or SSH key that was on disk when malware ran.

Authoritative references

Do this first (60 seconds)

  1. github.com/settings/tokensRevoke all.
  2. github.com/settings/tokens?type=beta → revoke fine-grained tokens too.
  3. github.com/settings/applications → review authorized OAuth apps.
  4. github.com/settings/security-log → look for suspicious activity in the last 24 hours.

Triage

What could the attacker do?

With a valid PAT:

  • Flip your private repos public. Shai-Hulud did this on first execution. Source code + committed secrets become world-readable.
  • Clone every private repo you have access to (yours + every org you're in).
  • Create new repos in your account to dump exfiltrated data (the Shai-Hulud repos / Dune-themed names from Mini Shai-Hulud).
  • Push to your repos, including malicious commits, force-pushes, release artifacts.
  • Add SSH keys / deploy keys for persistent access.
  • Read/write GitHub Actions secrets in repos where you have permissions.

Find every place the token lives

# gh CLI session
gh auth status

# Common token locations
cat ~/.config/gh/hosts.yml | grep -i token
grep -rE "ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9_]{82}" ~/.zshrc ~/.bashrc ~/.profile ~/.envrc 2>/dev/null

# Env vars in current shell
env | grep -i -E "GH_|GITHUB_"

# SSH keys
ls -la ~/.ssh/

Rotate

  1. Revoke every PAT (classic + fine-grained).
  2. Sign out everywhere: github.com/settings/security → "Sessions" → revoke all.
  3. Rotate SSH keys. Generate a new key, add to GitHub, delete the old one from Settings → SSH and GPG keys.
  4. Re-authenticate gh: gh auth logout && gh auth login — prefer browser-based login with 2FA over PATs.
  5. Audit deploy keys on every repo you own: Settings → Deploy keys — delete any you didn't add.
  6. Rotate GitHub Actions secrets in every repo. gh secret list -R OWNER/REPO to enumerate.
  7. Check organization access. If you're in an org, the attacker may have changed your role or added themselves; ask the org owner to review the audit log.

Audit damage

Were private repos flipped public?

gh repo list YOUR_USER --limit 100 --json name,visibility,createdAt,updatedAt | \
  jq '.[] | select(.visibility == "PUBLIC") | {name, updatedAt}' | head -50

Look for repos that should be private. Flip them back: gh repo edit YOUR_USER/REPO --visibility private.

If a private repo was public for more than a few seconds, assume forks exist. Search:

gh api "/search/repositories?q=fork:true+REPO_NAME+user:YOUR_USER" --jq '.items[] | .full_name'

Were new public repos created with exfil data?

gh api /user/repos --paginate --jq '.[] | select(.created_at > "DATE_OF_COMPROMISE") | {name, private, html_url}'

For any unexpected repo (Shai-Hulud, Mini Shai-Hulud Dune-themed, or generic exfil dumps), delete it (gh repo delete) but first download its contents — those are the secrets you now know to rotate.

Were secrets pushed as commits?

# In each repo, look for new commits authored from unfamiliar emails / times
git log --since="DATE_OF_COMPROMISE" --pretty=format:'%h %an <%ae> %ad %s'

Verify cloud creds too

Anything in .env files or env vars on the machine → rotating-cloud-credentials.md.

Prevention going forward

Best long-term moves: