We manage your security to weather the AI storm →

← Resource Hub

Private Key Exposed on GitHub: What to Do in the First Hour

By Owen Thurm Published 6 min read

Private Key Exposed on GitHub: What to Do in the First Hour

Quick answer. Assume it is already stolen: scanners can find a public commit within seconds. Move the funds and rotate every role the key holds first. Purging git history comes after, and it does not un-leak the key.

Watch: Private Key Exposed on GitHub: What to Do in the First Hour 1:30
Video transcript

Pushed a private key to GitHub? Assume it is already stolen. Scanners can find a public commit within seconds.

Attackers scan public GitHub activity live. Researchers found a pushed test string in a median of 20 seconds. Unit 42's AWS keys were used within five minutes, even after deletion, and one user reported a wallet emptied in under 100 seconds.

First, move the funds to a new wallet, then rotate every role and signer the key holds. Rotate the other secrets in the file, and clean git history last.

An admin key is worth more than its balance. Move ownership to a multisig, grant roles to a new key before revoking the old one, and have the other Safe owners swap the signer.

Purging history comes later, and does not make the key safe. GitHub warns you cannot remove sensitive data from other users' clones, and forks keep it too.

GitHub's supported secret patterns name no Ethereum, wallet or seed phrase format. Gitleaks and TruffleHog ship no wallet key rule either.

Keep production keys in encrypted keystores or hardware wallets, not dot env files. Add a custom Gitleaks rule for wallet keys, test it on a fake key, and run it in CI too.

Guardian maps the keys and roles that can move your funds. Read the full guide, or talk to Guardian about Managed Security.

A private key or seed phrase in a public repository is not a cleanup task. It is a theft in progress.

In May 2020, Decrypt reported one Reddit user's account of leaving a seed phrase in code on GitHub. By that account, a bot took $1,200 in ETH from the user's MetaMask wallet "in under 100 seconds."

This guide covers the first hour, the history cleanup and the controls that stop a repeat.

How Bots Find Keys

Nobody needs to find your repository by name. Attackers scan public GitHub activity as it happens.

Source What was exposed How fast
NC State researchers, NDSS 2019A test string pushed to a public repositoryFound by their scanner in a median of 20 seconds
Palo Alto Networks Unit 42, 2023AWS keys committed to public repositoriesUsed by an attacker within five minutes
Decrypt, 2020A seed phrase left in codeFunds gone "in under 100 seconds," by one user's account

Deleting the file does not stop it. Unit 42 deleted its keys right after committing them, and they were still found and used.

The NC State study scanned billions of files and found "thousands of new, unique secrets are leaked every day." Of the secrets it tracked, 81% had not been removed after about two weeks.

What to Do in the First Hour

Work in this order. Speed matters more than a tidy cleanup.

Move the funds

  1. Treat the key as compromised now. Do not wait for a theft to confirm it.
  2. Create a new wallet on a clean device, preferably a hardware wallet, as Revoke.cash advises.
  3. Move everything left from the exposed address to the new one.
  4. For a seed phrase, sweep every account. It "controls every address derived from it, across all chains."

If a sweeper bot is already active, sending ETH for gas "rarely works," Revoke.cash warns: "the bot sweeps it before you can use it."

For high-value funds still at risk, Revoke.cash points to the Flashbots Whitehat Hotline. SEAL 911, a volunteer group of security professionals, takes emergency tickets through its Telegram bot.

Our guide to a drained crypto wallet covers the rest of that response.

Rotate roles and signers

A deployer or admin key is worth more than its balance. Whoever holds it can use every power it still has.

  • Owner: transfer ownership to a multisig. With OpenZeppelin's Ownable2Step, the new owner must accept.
  • Roles: a role's admin can grantRole and revokeRole. Grant the new holder, then revoke the old key.
  • Safe signer: the other owners replace it with swapOwner, which runs only "via a Safe transaction."
  • The rest: pause, upgrade and mint rights, keeper and oracle keys, timelock proposers.

Our guide to private key management covers how to hold these keys afterward.

Rotate everything else in the file

A leaked .env rarely holds one secret. Rotate the RPC, explorer, cloud and bot keys beside the wallet key.

Then check where else the file went: forks, CI logs and build artifacts.

Cleaning the Git History

GitHub's own guide puts this second: "as a first step you need to revoke and/or rotate that secret."

A wallet key cannot be revoked. Moving funds and roles is your rotation, and rewriting history only limits further exposure.

GitHub recommends git-filter-repo, version 2.47 or later, with its sensitive-data flag:

git-filter-repo --sensitive-data-removal --invert-paths --path .env
git push --force --mirror origin

To scrub a string from every file instead, GitHub shows --replace-text. Expect side effects:

  • Every commit hash from the leak onward changes.
  • Branch protections that block force pushes must be turned off, at least briefly.
  • git-filter-repo strips commit and tag signatures, even on older commits.
  • It is "easy to re-push the sensitive data," GitHub warns, from any clone made before the rewrite.

What a purge cannot reach

  • Other people's clones. "You cannot remove sensitive data from other users' clones."
  • Forks that already contain the commit.
  • Cached views and pull requests on GitHub, until GitHub Support removes them.

The purge narrows who can still find the key. It does not make the key safe again.

Preventing the Next Leak

Keep production keys out of files

Foundry's best practices say to "Store production keys in encrypted keystores or hardware wallets" and keep .env files out of version control.

Its sample .env.example says: "Use cast wallet import instead of PRIVATE_KEY". Our Foundry deployment guide shows the setup.

A private repository is not a vault either. In September 2025, Wiz reported, the Shai-Hulud npm worm ran TruffleHog on infected machines.

It pushed stolen secrets to public GitHub repositories and republished some private repositories as public. Our supply chain guide covers that worm.

GitHub secret scanning and push protection

  • Secret scanning "runs automatically for free" on public repositories, across all branches and history.
  • Push protection for users is on by default and "Stops you from pushing secrets to public repositories."
  • Repository push protection needs GitHub Secret Protection. By default, anyone with write access can bypass it with a reason.

The gap: GitHub's list of supported patterns names no Ethereum, wallet or seed phrase format. Its generic private key patterns cover formats such as RSA, EC, OpenSSH and PGP.

Do not count on GitHub to catch a wallet key.

Pre-commit scanners

Gitleaks runs as a hook through the pre-commit framework. Add this, then run pre-commit install:

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.30.1
    hooks:
      - id: gitleaks

TruffleHog classifies over 800 secret types and checks whether found credentials are live. Its docs show a global hook through Git's core.hooksPath.

Neither ships a wallet key or seed phrase rule. Their private key rules look for PEM headers such as BEGIN PRIVATE KEY, which a raw hex wallet key lacks.

Gitleaks' generic API key rule may flag a KEY= line, but it is an entropy heuristic, not a wallet rule.

So add a rule. Gitleaks reads .gitleaks.toml from the repository root, and useDefault keeps its built-in rules. Here is an example to adapt:

[extend]
useDefault = true

[[rules]]
id = "evm-private-key"
description = "Hex private key assigned to a key-like name"
regex = '''(?i)private_?key\s*[:=]\s*["']?((?:0x)?[0-9a-f]{64})'''
secretGroup = 1
keywords = ["private"]

Match your own variable names and add a rule for mnemonic variables. Then test it with gitleaks dir on a sample file holding a fake key.

A hook only runs where it is installed, so run the same scan in CI.

How Guardian Helps

In Managed Security, Guardian's Sentry watches your domains, DNS, certificates, cloud and code host. When something fires, a Guardian engineer responds.

Shield, Guardian's attack surface management system, discovers every domain, website, IP, cloud service and repository you expose. Then it runs agents and pentests against them around the clock.

Managed Security's operational security work covers nine domains and 118 controls, including keys, signers, secrets and the pipeline that ships them.

Guardian also maps every path to your funds: the contracts, the roles that can move them and the keys behind each one. When a key leaks, that map is your rotation list.

An OpSec audit reviews secrets handling and release control before anything leaks.

Frequently Asked Questions

What happens if I accidentally push a private key to GitHub?

Treat it as stolen. In one study, a scanner found newly pushed strings in a median of 20 seconds. Anyone with the key can move its funds and use any role it holds until you move them.

Does deleting the commit fix it?

No. Clones and forks keep their copies, and GitHub's cached views and pull requests can still show the commit until GitHub Support removes them. Rewrite history only after moving funds and rotating roles.

Will GitHub secret scanning catch a wallet key?

Do not count on it. GitHub's list of supported patterns names no Ethereum, wallet or seed phrase format. Add a custom rule to a pre-commit scanner such as Gitleaks, and run it in CI as well.

Can I rescue tokens from a wallet a bot is sweeping?

Sending ETH for gas rarely works, because sweeper bots take it first. For high-value funds, Revoke.cash points to the Flashbots Whitehat Hotline, and SEAL 911 takes emergency tickets through its Telegram bot.

Sources

Know which keys can move your funds

Guardian maps every path to your funds and watches your code host and cloud, so a leaked key meets a rotation plan, not a scramble.