A Leaked AWS Access Key: Your First 60 Minutes
An access key ends up in a public repo, a CI log or a stolen laptop. This is a minute-by-minute playbook to scope the damage, contain the identity without breaking production, and close the doors the attacker opened.
Long-lived IAM access keys are still the most common way attackers get into AWS accounts. A key is
committed to a public repository, printed in a CI build log, left in a .env file on a laptop, or
pasted into a support ticket. Automated scanners watch public code hosts all the time, and a
leaked key is often tested within minutes of exposure.
When you get the alert — from a secret scanner, from AWS, or from a surprising bill — the clock is already running. This article is a practical playbook for the first hour. It assumes CloudTrail is enabled in the affected account, which is true for every AWS account by default for management events.
What the attacker does first
Knowing the usual sequence tells you what to look for. Most key-abuse incidents follow the same pattern, in roughly this order:
| Phase | Typical CloudTrail events | What they want |
|---|---|---|
| Validate the key | GetCallerIdentity |
Is the key live, and which account and identity is it? |
| Reconnaissance | ListBuckets, GetAccountAuthorizationDetails, ListUsers, DescribeInstances, DescribeRegions |
What can this identity reach? |
| Probe permissions | Many calls ending in AccessDenied |
Map the edges of the policy |
| Persistence | CreateAccessKey, CreateUser, CreateLoginProfile, CreateRole / UpdateAssumeRolePolicy with an external principal |
Keep access after you rotate the key |
| Monetize | RunInstances (often large GPU types in unused regions), GetSecretValue, GetObject in bulk |
Crypto-mining, secrets, data theft |
| Cover tracks | StopLogging, DeleteTrail, PutEventSelectors, DeleteFlowLogs |
Blind you |
Two things in this table matter for your response. First, much of the early activity is
read-only (Get*, List*, Describe*). If your logging or event forwarding only keeps write
events, you will miss the reconnaissance phase entirely. Second, persistence usually happens
before monetization. Rotating the leaked key is necessary, but it is rarely enough.
Minutes 0–10: Scope the key
Before you touch anything, answer three questions.
- Which identity owns this key? An access key ID (
AKIA…) belongs to exactly one IAM user. Find the user and the account. - Is the key being used right now, and from where? List the source IP addresses and countries that used this key in the last days. Your own CI runners and office IPs are expected. A residential proxy range or a hosting provider in a country where you have no staff is not.
- What else did those IP addresses do? Attackers often test several stolen keys from the same infrastructure. If a suspicious IP used a second identity, you have a second incident.
Write the answers down. The IP list becomes your filter for the next phase.
Minutes 10–25: Reconstruct the timeline
Now look at everything the identity did, oldest event first, starting a little before the suspected exposure time. Work through the phases in the table above and mark each one as seen or not seen.
Look especially for:
- A burst of
AccessDeniederrors. Ten or more denied calls in a few minutes is a strong sign of someone probing permissions they do not know. - Activity in regions you never use. Attackers launch instances where nobody is looking.
- Any new credential. A new access key, a console password on a user that never had one, or a role whose trust policy now includes an account you do not recognize. Each one is a door that stays open after rotation.
- Changes to logging. A
StopLoggingcall is not an accident during an incident.
At the end of this phase you should know whether this is "a key that leaked but was never used" or "an active intrusion", and which resources were touched.
Minutes 25–35: Contain without breaking production
The instinct is to delete the key. Resist it for a moment. The leaked key may belong to a production integration — a payment export, a nightly backup, a partner feed — and deleting it at 14:00 on a Tuesday can cause a second incident.
Contain in a way you can undo:
- Attach a deny-all policy to the IAM user. An explicit deny overrides every allow, so the identity immediately loses all access, including through the leaked key. Detaching the policy restores it exactly as it was.
- Deactivate (do not delete) the access keys. A deactivated key can be re-activated in one call if you find a critical dependency. Deletion is permanent.
- Revoke active sessions if the user can assume roles. Temporary credentials issued before containment stay valid until they expire, so check which roles the user assumed.
Record every action, who took it, and what the inverse is. When the business owner of the integration calls, you want to answer with facts, and restore service in minutes if needed.
Minutes 35–60: Close the doors and harden
Containment stops the bleeding. Now remove what the attacker left behind and make the next detection faster.
Eradicate:
- Delete access keys, users, login profiles and roles created by the attacker.
- Revert trust policy changes that added external principals.
- Terminate unauthorized instances (take a snapshot first if you need forensics).
- Re-enable any logging that was stopped.
- Issue a new key to the legitimate owner, update the integration, then delete the old key. Better: move the integration to an IAM role so there is no long-lived key to leak.
Detect next time. Turn what you just learned into rules that run all the time:
| Detection | Signal | Suggested first response |
|---|---|---|
| Credential probing | 10+ AccessDenied for one identity in 5 minutes |
Notify |
| IAM reconnaissance | GetAccountAuthorizationDetails |
Notify |
| New access key | CreateAccessKey |
Notify |
| Console password added | CreateLoginProfile, UpdateLoginProfile |
Notify |
| Backdoor role | Trust policy grants an external principal | Notify, then contain |
| Unexpected country | Activity from a country outside your policy | Notify with one-click containment |
| Logging tampering | StopLogging, DeleteTrail, PutEventSelectors |
Re-enable logging and notify |
The one-page checklist
- Identify the IAM user and account that own the key
- List source IPs and countries that used the key; check them against other identities
- Build the timeline, including read-only events
- Mark reconnaissance, persistence, monetization and tampering as seen or not seen
- Attach a deny policy and deactivate the keys (reversible)
- Remove attacker-created keys, users, login profiles and role trusts
- Re-enable logging, remove unauthorized compute
- Replace the key with a role where possible
- Add standing detections for the patterns you found
How AWS Cloud Governance helps
AWS Cloud Governance runs inside your own AWS account and puts every step of this playbook on one screen:
- Scope in seconds. Search an access key ID or IP address on the Entities page to see every principal that used it, the other keys and IPs of those principals, and their denied calls over the last 30 days.
- Actor timelines. The Events explorer groups all CloudTrail activity by the identity behind it, with a timeline, profile and activity graph — including read-only management events.
- Reversible containment. Contain the IAM user with one click, or deactivate its access keys. Every action is recorded in the Actions log with a Rollback button, so releasing a production integration is one click too.
- Standing detections. Pre-built templates cover every row in the detection table above. Start them as notify-only rules; alert emails can include a single-use, 24-hour containment link.
You can try it free for 3 months at https://trustpartners.tech.