My AWS Access Key Was Leaked on GitHub β What Do I Do Now?
You pushed a commit, realized your AKIAβ¦ key was sitting right there in the diff, and your stomach dropped. Here is exactly what to do β in order β before anything bad happens.
Last updated: July 1, 2026 Β· 20 min read
Speed is everything here
Bots scan GitHub commits for AWS keys within seconds of a push. If the repository is public, assume the key is already compromised and act accordingly. Even if it's private, treat it the same way β leaked credentials have no grace period.
It happens to almost every developer at least once. You're working fast, you hardcode a key to test something locally, you forget to add it to .gitignore, and then β commit, push, done. A second later you spot it in the diff and your brain goes into full panic mode.
First: breathe. This is recoverable. AWS gives you the tools to contain the situation quickly, and if you move fast enough, the damage can be zero. The steps below are ordered by priority β do them in sequence, don't skip ahead.
Step 1 β Revoke the key immediately
β± Target: under 2 minutes
Before you do anything else β before deleting the commit, before opening CloudTrail, before texting your team β you need to kill that key. A deactivated key is worthless to an attacker.
Option A: AWS Console (fastest for most people)
- Go to IAM β Users β [your user] β Security credentials
- Find the leaked key (starts with
AKIAorASIA) - Click Make inactive β this instantly blocks any requests using that key
- Then click Delete β don't leave it sitting there even as inactive
Option B: AWS CLI (if you have another working key)
# Deactivate first aws iam update-access-key \ --access-key-id AKIAIOSFODNN7EXAMPLE \ --status Inactive # Then delete it entirely aws iam delete-access-key \ --access-key-id AKIAIOSFODNN7EXAMPLE
β οΈ Don't just delete the key from GitHub
Deleting the file or the commit does not revoke the credentials. The key still works in AWS until you deactivate it there. GitHub history removal comes later β step 2.
Step 2 β Remove it from Git history
Once the key is revoked, the urgency drops β but you still need to clean up the repository. Git history is persistent. Even if you delete the file in a new commit, the key remains visible in every previous commit forever. Anyone who cloned the repo before you noticed has a full copy.
If the repo is public β act fast
Make the repository private immediately while you clean up. GitHub's own scanning bots may have already flagged it (they'll send you an email), but making it private buys you time.
Rewrite history with git-filter-repo
The modern, recommended way to scrub sensitive data from Git history is git-filter-repo. It replaces the old BFG Repo Cleaner and is much safer than git filter-branch.
# Install (Python required) pip install git-filter-repo # Replace the key in all commits with a placeholder git filter-repo --replace-text <(echo "AKIAIOSFODNN7EXAMPLE==>REMOVED_KEY") # Force-push the rewritten history git push origin --force --all git push origin --force --tags
After force-pushing, anyone who had cloned the repo should re-clone it fresh. Inform your team so they don't accidentally push the old history back.
Ask GitHub to clear caches
Even after rewriting history, GitHub caches old commits for a while. You can request a cache purge through GitHub Support β navigate to Settings β Code security β Contact support and explain the situation. They're used to handling this.
Step 3 β Audit what was accessed
Now that the bleeding is stopped, you need to understand if anything was actually done with the key. AWS CloudTrail is your best friend here β it logs every API call made under your account.
Check CloudTrail immediately
- Go to CloudTrail β Event history in the AWS Console
- Filter by Access key ID β enter the leaked key
- Look at the last 24β72 hours depending on when you pushed
- Check for anything unusual: new IAM users, S3 downloads, EC2 launches, Lambda creates
Red flags to look for
New IAM users or roles created
CriticalEC2 instances launched (especially large ones)
CriticalS3 buckets accessed or data downloaded
HighLambda functions created or modified
HighNew access keys generated for other users
CriticalAPI calls from unusual geographic regions
MediumCheck billing for spikes
Attackers who get AWS keys almost always spin up compute resources for crypto mining or send mass emails via SES. Go to Billing β Cost Explorer and look for any sudden cost spike. If you see EC2 or SES charges you don't recognize, you've been hit.
If charges appear that aren't yours, report them to AWS Support immediately. AWS has a track record of waiving fraudulent charges when the incident is reported promptly and the key is provably compromised through an accidental leak.
Step 4 β Check for damage and clean up
If CloudTrail shows suspicious activity, you need to work through each service that was touched. Here is a fast checklist:
Check for new users, roles, policies, or access keys that were created. Delete anything you don't recognize. Review all existing user permissions for unexpected changes.
Terminate any instances you didn't launch. Check all regions β attackers spin up instances in regions you don't normally use to avoid billing alerts.
Review bucket access logs. Check if any buckets were made public. Look for large GetObject or ListBucket operations on sensitive data.
Delete any unknown functions. Check if existing functions were modified β attackers sometimes inject backdoors.
Check send statistics for unexpected spikes. SES is a common target for sending spam at your expense and reputation.
Look for DNS changes or new distributions β these can redirect your users to phishing pages.
Step 5 β Rotate and replace securely
With the old key gone and your account confirmed clean, you need to create a new key β and this time, store it properly.
Create a new key with minimal permissions
This is the perfect moment to revisit the permissions on the IAM user. If the leaked key had admin access, that's the real problem β a key should only have the exact permissions it needs, nothing more. This is the principle of least privilege.
# Create a new key for a specific user aws iam create-access-key --user-name my-deploy-user
Where to store credentials properly
AWS Secrets Manager
RecommendedBest for application secrets. Supports automatic rotation, audit logging, and fine-grained access control.
AWS Parameter Store (SSM)
GoodLighter-weight option for config and secrets. Free tier available. Good for smaller projects.
Environment variables via CI/CD
GoodGitHub Actions secrets, GitLab CI variables, Vercel env vars. Never committed to the repo.
IAM roles (for EC2/Lambda/ECS)
Best when possibleThe best option when your code runs on AWS infrastructure β no keys at all, just a role.
.env files
Local onlyOnly acceptable locally. Must be in .gitignore. Never for production.
Step 6 β Make sure this never happens again
The key is revoked, the history is clean, and your account is secure. Now let's make this structurally impossible to repeat.
1. Use a pre-commit hook to block secrets
Install git-secrets or detect-secrets to scan every commit before it leaves your machine:
# Install git-secrets brew install git-secrets # macOS # or: pip install detect-secrets # Set it up in your repo git secrets --install git secrets --register-aws # Now any commit containing AWS key patterns will be blocked
2. Enable GitHub secret scanning
GitHub automatically scans public repositories for known credential patterns and notifies you (and sometimes the service provider). For private repos, it's available on GitHub Advanced Security. Go to Settings β Code security β Secret scanning and make sure it's enabled.
3. Add a global .gitignore
Create a global .gitignore on your machine that permanently ignores common secret files across all repositories:
# Create ~/.gitignore_global echo ".env .env.local .env.*.local *.pem *_rsa credentials aws-credentials.json secrets.json *.key" >> ~/.gitignore_global # Tell git to use it git config --global core.excludesfile ~/.gitignore_global
4. Enable AWS CloudTrail (if not already on)
CloudTrail should always be enabled β ideally logging to an S3 bucket you don't normally touch, with MFA delete enabled on that bucket so logs can't be tampered with. If an incident happens, you want a complete, trustworthy audit trail.
5. Set billing alerts
Go to Billing β Budgets and create an alert that fires when your spend exceeds your normal monthly ceiling. This won't prevent a breach, but it catches the most common attack pattern β crypto mining β within hours instead of days.
6. Prefer IAM roles over long-lived keys
If your application runs on AWS (EC2, ECS, Lambda, CodeBuild), you don't need access keys at all. Assign an IAM role to the resource, and AWS handles the temporary credentials automatically. No key to leak means no leak.
FAQ β Common questions after a leak
The repo was private. Am I safe?β
The key was only in the diff for 30 seconds. Is it already compromised?β
Will AWS waive the fraudulent charges?β
Do I need to report this to anyone?β
Should I delete the entire repo and start fresh?β
I deleted the file in a new commit. Isn't that enough?β
Quick recap β the six steps
- 1Revoke the key in IAM immediately β deactivate, then delete
- 2Remove it from Git history using git-filter-repo, then force-push
- 3Audit CloudTrail for activity on that key in the past 24β72 hours
- 4Clean up anything suspicious: rogue IAM users, unknown EC2 instances, modified Lambdas
- 5Create a new key with least-privilege permissions and store it in Secrets Manager or SSM
- 6Add pre-commit hooks, enable GitHub secret scanning, and set billing alerts