How to audit leaked secrets on GitHub and revoke access
Learn how to spot exposed credentials in your code, clean Git history using specialized tools, and automate scans to protect your repository.
Summary
- Credentials left behind in source code can be discovered by automated bots within minutes of a public commit.
- Simply deleting a file in the current commit does not erase confidential data saved deep within Git history.
- Specialized scanning tools can sweep through entire codebases looking for known patterns of keys and passwords.
- Immediately revoking compromised access minimizes exposure time before attackers exploit your systems.
- Automating checks in the development workflow prevents future leaks from occurring in upcoming deployments.
The silent danger of exposed credentials in your code
When writing software, it is common to use access keys, database passwords, and API tokens for local testing. The major problem occurs when we leave these confidential items, known as secrets, inside the source code and push everything to a public repository on GitHub. In practice, this means any malicious bot scanning the internet can find these keys within minutes and use them to break into servers, extract data, or perform financial actions on your behalf. The damage can be massive, requiring an immediate and coordinated response from the engineering team.
Even if you notice the mistake quickly and delete the file with the password in the very next commit, the damage might still be done. Git, the system we use to track code versions, keeps a complete history of everything ever pushed. This means the old password remains recorded deep within the repository, accessible to anyone who knows where to look. Before diving into complex cleanup tasks, an indispensable first step is ensuring the integrity of the rest of your project and related tooling, as detailed in our guide on how to protect branches in GitHub and prevent bad merges.
The impact of a leaked key goes far beyond the affected application. Often, a single cloud access key grants unrestricted passage to an entire company infrastructure. For this reason, proper credential management must go hand in hand with corporate security strategies, aligning with best practices for secret and credential management in continuous deployment cycles to prevent future exposures. Identifying the leak is only the beginning; the response must be surgical and precise.
How to identify hidden keys and passwords in your code
The first step to solving the problem is knowing exactly what was exposed. Doing this manually, reading file by file, is unfeasible for medium or large projects. To automate this hunt for lost treasures, we use dedicated tools designed to inspect code for specific patterns, such as long alphanumeric sequences resembling API tokens from AWS, GitHub, or payment gateways.
One of the most popular and efficient tools for this task is TruffleHog or Gitleaks. They examine both current files and the entire repository history, searching for known credential signatures. In practice, you run the program pointing to your local project folder, and it generates a detailed report pinpointing the exact line and commit where the leaked key appeared. If your team relies on complex branching workflows, it is worth understanding how to use Git Rebase safely in a team without breaking code before applying deep fixes to your history.
Below, see a practical example of how to run a quick scan using Gitleaks directly in your terminal:
# Install Gitleaks via package manager (macOS example)brew install gitleaks# Run a scan on the current repository and save the report as JSONgitleaks detect --source . --report-path report.json --verboseThis command sweeps through every piece of Git history and points out where secrets reside. With the report in hand, your team knows precisely which keys were compromised and must immediately begin the revocation process in the respective service dashboards.
The right strategy to revoke access and invalidate tokens
Identifying the leak and scanning the code are fundamental steps, but the core of risk mitigation is the immediate invalidation of the exposed credential. If an OpenAI or AWS API token has spilled into the wild, it must be neutralized in the provider dashboard before anything else happens. In practice, revocation tells the system that the key is no longer valid, blocking any future unauthorized attempts to use it.
After revoking the old access, the developer must generate a new credential and inject it into the application using secure environment variables or dedicated password vaults. Never store passwords directly in source code or unprotected local configuration files. Using .env files excluded from version control helps keep development clean, provided those files are never accidentally committed.
Aside from swapping out the leaked password or token, checking access logs on the affected service is vital. Find out if the attacker actually used the key during the period it was public. Analyze unknown IP addresses, requests made outside business hours, or abnormal spikes in resource consumption. This forensic investigation ensures you understand the true scope of the issue and can take additional steps, such as notifying customers if sensitive data was accessed.
Cleaning up deep Git history
Deleting a file from the current commit does not remove the secret from the Git database. To permanently purge confidential data from history, we must rewrite the repository's past. Tools like BFG Repo-Cleaner or the native git filter-repo command are industry standards for this delicate surgery. In practice, these tools replace the secret string with asterisks or remove the file entirely from all previous commits.
It is worth noting that rewriting history alters the identifiers (hashes) of all modified commits. This means that if other people are working on the same project, they will need to carefully sync their environments to avoid corrupting the remote repository. Below is an example of how to use git filter-repo to remove an entire file containing passwords:
# Make sure you have python and git-filter-repo installed# Remove the credentials file from the entire repository historygit filter-repo --path config/secrets.yml --invert-paths# Force push to the remote repository to overwrite old historygit origin push --force --allOnce this command runs, the problematic file ceases to exist in any previous version of the project. All collaborators will need to re-clone the repository or pull changes forcefully to align their local copies with the new, clean reality.
Automating scans to prevent future leaks
The best way to handle leaked secrets is to prevent them from ever reaching GitHub. To achieve this level of operational maturity, we implement pre-commit hooks and automated checks within continuous integration (CI/CD) pipelines. In practice, this creates an unbreakable barrier that blocks the git push command if any suspicious pattern is detected in modified files.
Tools like pre-commit let you configure automatic checks on every developer's machine before code leaves the local computer. If someone accidentally tries to commit a file containing an API key, the terminal displays a clear error and stops the action. This educational approach continuously strengthens team security culture, turning prevention into a daily habit.
Integrating these scans into continuous integration servers adds a second line of defense. Even if a developer ignores local warnings, the build pipeline will automatically fail upon detecting any exposed credential in the remote repository. Consequently, security stops relying solely on human attention and becomes guaranteed by automated, resilient processes.
Leaking secrets on GitHub is a stressful incident, but perfectly manageable if the team acts quickly, methodically, and in an organized manner. Combining deep Git history scans, immediate access revocation in cloud providers, and preventive automation ensures the mistake is never repeated. Remember that information security is a continuous journey of improving the processes and tools we use daily in software development.
By establishing rigorous review routines and investing in team education, we turn vulnerabilities into opportunities to learn and strengthen infrastructure. Keep your environments monitored, use proper password vaults, and ensure your codebase remains forever free of unwanted surprises.