How to find leaked or compromised AWS credentials
Topic: Accounts access
Summary
Detect AWS access keys or credentials that may be leaked or compromised: search code and public repos, check CloudTrail for anomalous use, use AWS credentials report and last-used, and revoke keys immediately when found. Use this when you suspect a key was exposed or for periodic audits.
Intent: How-to
Quick answer
- Search code, config, and CI for access key IDs (AKIA...) and ensure secrets are not in plaintext; use git history and public repo scanners; check GitHub secret scanning and AWS Partner notifications for leaked keys.
- Review CloudTrail for unexpected regions, times, or APIs from the key or user; use get-access-key-last-used and credentials report to find unused or stale keys to rotate or remove.
- When a key is leaked or compromised, revoke it immediately (deactivate and delete); rotate to a new key or migrate to a role and investigate how it was exposed.
Prerequisites
Steps
-
Search for keys in code and config
Grep for AKIA (access key ID prefix), aws_access_key, and secret key patterns in repos, config files, and CI variables; check git history for removed-but-committed keys; use GitHub secret scanning and AWS notification if key was public.
-
Check CloudTrail and last-used
For each key or user, use get-access-key-last-used and CloudTrail filtered by userIdentity (accessKeyId or user name); look for sign-in or API calls from unexpected IPs, regions, or at unusual times.
-
Use credentials report and IAM Access Analyzer
Run generate-credentials-report and inspect password_last_used and access_key_1_last_used; enable and review IAM Access Analyzer findings for external access or over-permissive policies that could indicate misuse.
-
Revoke and rotate
When a key is confirmed or suspected leaked, deactivate it immediately (update-access-key --status Inactive), then delete it; create a new key or migrate to a role for the workload; document and fix the exposure (remove from repo, rotate secrets).
Summary
You will find leaked or compromised AWS credentials by searching code and config for key patterns, checking CloudTrail and last-used for anomalous activity, using the credentials report and Access Analyzer, and revoking keys immediately when exposure is confirmed or suspected. Use this for incident response and periodic audits.
Prerequisites
- IAM permissions to list users, list and get access key last used, and optionally generate credentials report and view CloudTrail.
- Ability to search repositories and config (grep, CI, or secret scanning).
Steps
Step 1: Search for keys in code and config
- Code and config: Search for
AKIA(access key ID prefix),aws_access_key_id,AWS_SECRET_ACCESS_KEY, and similar in source trees, config files, and CI/CD variable names. Do not log or display full secrets; check env files and example configs that might have been committed. - Git history: Run
git log -p -S 'AKIA'(or use a secret-scanning tool) to find keys that were committed and later removed; consider those keys compromised and revoke them. - Public exposure: If AWS or GitHub notifies you of a leaked key (e.g. in a public repo), treat it as compromised and revoke immediately. Check AWS Partner Network and public scanners for your key IDs if you have reason to believe they were exposed.
Step 2: Check CloudTrail and last-used
- Last-used: For each IAM user, list access keys and run
get-access-key-last-used; note last used time and region. Stale or unexpected use can indicate compromise or a forgotten consumer. - CloudTrail: In CloudTrail (or Lake), filter by
userIdentity.accessKeyIdoruserIdentity.userNameand a time range. Look for: sign-in or API calls from unexpected source IPs or regions, calls at unusual times, or sensitive actions (e.g. CreateUser, CreateAccessKey, DeleteBucket) that the user normally does not perform. Export and correlate with known operations.
Step 3: Use credentials report and IAM Access Analyzer
- Credentials report:
aws iam generate-credentials-reportthenget-credentials-report; parse password_last_used and access_key_1_last_used (and _2). Use this to find unused keys and users for cleanup or rotation. - Access Analyzer: If IAM Access Analyzer is enabled, review findings for external access to resources or over-permissive policies that could allow misuse. Address critical findings and revoke or narrow access as needed.
Step 4: Revoke and rotate
When a key is confirmed or strongly suspected leaked:
- Deactivate it immediately:
aws iam update-access-key --user-name USER --access-key-id KEY_ID --status Inactive - Delete it after confirming no legitimate use:
aws iam delete-access-key --user-name USER --access-key-id KEY_ID - Create a new key for the workload (or migrate to an IAM role) and update all legitimate consumers. See How to revoke an IAM user immediately and How to rotate access keys used by applications.
- Remove the secret from any repo, config, or artifact where it was exposed; rotate any other secrets that may have been in the same place. Document the incident and how the leak occurred.
Verification
- No access key or secret appears in source code, config, or public artifacts; secret scanning and grep do not find live keys.
- CloudTrail and last-used show no anomalous use for remaining keys; credentials report is reviewed and stale keys are removed or rotated.
- Any compromised key is deactivated and deleted; new key or role is in place and consumers updated.
Troubleshooting
Key ID found in code but not sure if still active — Assume it is compromised. List access keys for the user; if that key ID exists, deactivate and delete it. Create a new key and update consumers; remove the key from code and history (e.g. BFG or filter-branch to remove from git history if policy allows).
CloudTrail shows unexpected region — Could be legitimate (e.g. global service) or compromise. Cross-check with the user/key owner and known operations. If unexplained, revoke the key and force rotation; require MFA for sensitive roles.
Many keys to review — Prioritize keys with broad permissions (e.g. AdministratorAccess) and keys that appear in code or public repos. Use credentials report to sort by last_used and focus on recently used and never-used keys first.