{"slug": "deleting-a-leaked-key-from-your-repo-doesn-t-protect-you", "title": "Deleting a leaked key from your repo doesn't protect you", "summary": "LiteLLM developers leaked an administrative key in a public GitHub commit in May and attackers used the credential to compromise their infrastructure months later, according to the company's post-mortem on the October 21, 2026 attack chain. The post-mortem states that a follow-up commit deleted the file about three hours after the leak and the keys were noted as requiring revocation, but the original commit stayed in the repository's public history until October 22, when LiteLLM rewrote git history. The incident illustrates that deleting a file, rewriting commit history or deleting a repository does not protect a leaked secret, because secret scanners and attackers parse git history and GitHub still serves unreachable commits to anyone with the SHA-1 hash; only rotating the credential does.", "body_md": "*tl;dr If you leak a secret, rotate it immediately. Deleting a file, rewriting git commit history or deleting your repository won't protect you. Attackers routinely scan the internet for secrets, so assume they already have a copy. Use* *Betterleaks* *or* *Aikido Secrets Detection* *to find leaked secrets in your repos, and* *Aikido Device Protection* *to find them on developer machines.*\n\nIn May, LiteLLM developers accidentally committed an administrative key to a public GitHub repository. Attackers used that credential to compromise their infrastructure months later.\n\nLiteLLM’s [post-mortem](https://docs.litellm.ai/blog/security-incident-oct-21-2026-attack-chain) documents the timeline of their actions to fix the leak. One sentence from the report stuck out to me:\n\n*“About three hours later a follow-up commit deleted the file [that leaked the secret] and the keys were noted as requiring revocation, but the original commit stayed in the repository's public history until October 22.”*\n\nLiteLLM caught the leak within 3 hours. Their first corrective action was [this Pull Request](https://github.com/LiteLLM-Labs/lite-harness/pull/7) that simply deleted the file. Months later, on October 22, they rewrote git history to remove the [commits](https://github.com/LiteLLM-Labs/lite-harness/commit/25330ee80c82d7ecc9e988cec0f3cff8eace5419) that leaked the credential.\n\nThose two actions, while common, reflect general misconceptions among developers about secret leakage in git history. Neither step LiteLLM took actually prevents anyone from viewing the leaked data. In fact, [the commit](https://github.com/LiteLLM-Labs/lite-harness/blob/e10b14a/harnesses/opencode/opencode.json) leaking the credential is still visible today (don’t worry, they’ve since rotated it!).\n\nThe **only** way to fully fix a leaked credential is to rotate that credential. Once it’s public, it’s no loner a secret, and won't be again.\n\n## Common Misconceptions about Leaked Secrets in Git\n\nThe experiments below each test a common \"fix\" for leaked secrets in git repos:\n\nNone of these actions fully protects you from threat actors discovering and using a secret you leak. Even if it’s only in public for just a few minutes.\n\n## Misconception #1: Delete the file\n\nLiteLLM took this approach immediately after discovering the leak and it’s probably the most common reaction. The developer recognized a mistake in their code, so they “fixed” it by deleting the offending file in a new commit. As we’ll see below, secret scanners parse git history and scan deleted files.\n\n1. Create a new local git repo. Commit a README. Then commit a file with a secret in it.\n\n```\nmkdir tmp_repo\ncd tmp_repo\ngit init\necho \"# README\" > README.md\ngit add README.md\ngit commit -m \"initial commit\"\n# fake leaked key\necho \"secret_token=ZQ5Cl16U8kmc4uOxS581xDWr\" > file.txt\ngit add file.txt\ngit commit -m \"exposing secret in file.txt\"\n```\n\n1. Delete that file. Commit again.\n\n```\nrm file.txt\ngit add .\ngit commit -m \"removed exposed secret in file.txt\"\n```\n\n1. Scan using [Betterleaks](https://github.com/betterleaks/betterleaks) . You’ll see it detects a secret in git history. (Instructions for setting up Betterleaks on the GitHub page.)\n\n```\nbetterleaks git .\n```\n\n## Misconception #2: Rewrite git history\n\nThe next instinct is usually to \"erase\" the leak from git history. LiteLLM attempted this on October 22 by force pushing a rewritten history that excludes the relevant commits. On the surface this seems to work, since those commits aren’t reachable from any branch. Unfortunately, GitHub still serves \"deleted\" commits to anyone who has their SHA-1 hash.\n\n1. Record the commit SHA-1 hash where you exposed the secret.\n\n```\ngit log --format=%H --grep=\"exposing secret in file.txt\" -1\n```\n\n*Note: SHA-1 hashes are 40 characters, which is way too long to guess. However, GitHub allows users to provide a short version in their UI, which resolves to the full 40 characters. The short version can be as short as 4 characters (0-9a-f), which makes these hashes more easily discoverable.*\n\n1. Push the local repo from above to GitHub. *(Create the repo on the GitHub website if the first command doesn’t work.)*\n\n```\ngit remote add origin https://github.com/<github-username>/tmp_repo.git\ngit branch -M main\ngit push -u origin main\n```\n\n1. Reset your git head to the first commit. Force push to GitHub.\n\n```\ngit reset HEAD~2 --hard\ngit push --force\n```\n\n*Note: There are different ways to rewrite commit history. This is a simple demo, so all we’re doing is resetting our repository back to the first initial commit and then force pushing it.*\n\n1. Delete your local repo.\n\n```\ncd ..\n# rm -r tmp_repo # double check your directory name before running this\n```\n\n1. Clone the remote.\n\n```\ngit clone https://github.com/<user>/tmp_repo.git\ncd tmp_repo\n```\n\n1. Review your git history in the cloned version. It will only show one commit.\n\n```\ngit log\n```\n\n1. Fetch your “deleted” commit directly from GitHub. View the “deleted” file.\n\n```\ngit fetch origin <sha1_hash_from_step_1>\ngit checkout <sha1_hash_from_step_1>\ncat file.txt\n```\n\nIf you visit the “deleted” commit in the browser, you’ll see a banner up top that says “This commit does not belong to any branch on this repository…”, yet we can still see it.\n\n```\nhttps://github.com/<user>/tmp_repo/commit/<sha1_hash_from_step_1>\n```\n\n## Misconception #3: Delete the repo\n\nAs a last resort, developers often delete the entire repository. Unfortunately, this isn’t sufficient either. First, you have zero visibility into who cloned your repository. Second, if anyone forked your repository, GitHub will keep a copy of your “deleted” commit indefinitely.\n\n1. Ask a friend to fork the repository we created above.\n2. Delete your repository.\n3. Visit the deleted commit (via hash) on your friend’s forked version.\n\n```\nhttps://github.com/<friend>/tmp_repo/commit/<sha1_hash_from_step_1>\n```\n\nThe commit containing your leaked data will live indefinitely on GitHub until the last fork is deleted.\n\n### What if no one saw it?\n\nIf those experiments weren’t enough to convince you that you need to rotate a credential that is exposed publicly, watch our colleague Mackenzie [leak a key live at a conference](https://youtu.be/XsuZQwK3m5c?si=jPjV1eWL0Dr2YLj7&t=1051), and then [check how many actors scanned his key](https://www.youtube.com/watch?v=XsuZQwK3m5c&t=1523s) within just a few minutes. Researchers, SaaS/Cloud platforms, and threat actors are all scanning for secrets constantly. Assume that the moment it’s public, someone has seen it.\n\n## Rotate your exposed keys\n\nDeleting a file, rewriting history, and deleting a repo all leave a leaked secret reachable. The only action that fully protects your account is credential rotation:\n\n- revoke the leaked one\n- issue a new one\n- update everywhere the old one was used\n\nWhile credential rotation stops future misuse, it doesn’t do anything about misuse that already happened, and a leaked key can sit for months before someone finds it. LiteLLM's key was live for over four months before an attacker used it to pull a GitHub token and ship a malicious release.\n\nAfter you rotate, check for signs the old key was already used:\n\n- The key or token's own usage and access logs\n- Recent commits to main and any protected branches\n- CI and workflow config changes, and recent pipeline runs\n\nIf you can't rule out misuse, treat it as an incident.\n\n## How Aikido helps\n\nAikido helps you check if you have leaked secrets. Customers get secrets detection built into the Aikido platform, and anyone can run Betterleaks, the free open source engine that powers it.\n\n### Aikido Secrets Detection and Device Protection\n\nConnect your GitHub, GitLab, Bitbucket or Azure DevOps repositories, public or private, and [Aikido Secrets Detection](https://www.aikido.dev/code/secrets-detection) checks them for API keys, passwords, tokens and other exposed credentials. It looks at current code by default, and you can turn on full Git history checks to catch secrets that were added and later removed, like the deleted file from misconception #1.\n\nThe Betterleaks engine pairs known credential patterns with techniques for catching generic secrets. For supported credential types, [Live Secret Detection](https://help.aikido.dev/code-scanning/scanning-practices/live-secret-detection) checks whether a leaked secret is still active and adjusts the issue’s severity to match. [Secrets AutoTriage](https://help.aikido.dev/aikido-agent/secrets-autotriage) uses context to separate real credentials from example or test values.\n\nAikido also flags secrets earlier in development. IDE extensions and a [pre-commit hook](https://help.aikido.dev/ai-and-dev-tools/aikido-secrets-pre-commit-hook) warn developers before a secret reaches a commit. In CI/CD, Aikido can block a build or PR that contains one.\n\n[Aikido Device Protection](https://help.aikido.dev/aikido-device-protection/miscellaneous-aikido-endpoint/how-does-endpoint-protection-work) adds a layer on developer machines. Its agent looks through local files on the device, such as shell history, for hardcoded secrets. File contents stay on the device. When the agent finds a secret, Aikido receives the type of secret and a few characters of the value, enough to recognize the finding.\n\n### Betterleaks\n\nAnyone can run [Betterleaks](https://github.com/betterleaks/betterleaks) on its own. Aikido sponsors the project, and it’s free under the MIT license. The original author of Gitleaks built it as a drop-in replacement for Gitleaks.\n\n**Reminder: Whichever tool finds a leaked secret, rotate it.** Aikido flags active credentials and recommends rotating them; revoke and replace the credential with the service that issued it. Deleting the secret from your latest commit leaves it in Git history, as the experiments above show.", "url": "https://wpnews.pro/news/deleting-a-leaked-key-from-your-repo-doesn-t-protect-you", "canonical_source": "https://www.aikido.dev/blog/leaked-api-key-revoke-it-immediately", "published_at": "2026-11-05 17:07:00+00:00", "updated_at": "2026-11-05 17:52:56.330473+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools"], "entities": ["LiteLLM", "GitHub", "Betterleaks", "Aikido Secrets Detection", "Aikido Device Protection"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/deleting-a-leaked-key-from-your-repo-doesn-t-protect-you", "markdown": "https://wpnews.pro/news/deleting-a-leaked-key-from-your-repo-doesn-t-protect-you.md", "text": "https://wpnews.pro/news/deleting-a-leaked-key-from-your-repo-doesn-t-protect-you.txt", "jsonld": "https://wpnews.pro/news/deleting-a-leaked-key-from-your-repo-doesn-t-protect-you.jsonld"}}