AWS Compromised Access Key: Immediate Response and Investigation Guide

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
An exposed AWS access key is one of the fastest-moving security incidents you will face. Automated scanners continuously monitor GitHub commits, Pastebin, public S3 buckets, and other common leak locations for AWS key patterns (AKIA... prefix). A key exposed in a public GitHub commit is typically detected and first used within 2-5 minutes. The attacker's first actions are predictable: create backdoor IAM credentials, launch EC2 instances in multiple regions for crypto mining, and exfiltrate any S3 data they can find — all before most teams finish their morning standup.
The incident response sequence is counterintuitive: deactivate first, investigate second. Every extra minute the key remains active is potential additional attacker activity. This guide covers the full response: immediate containment, cross-region blast radius investigation, attacker persistence hunting, and the architectural changes that make key exposure structurally less damaging.
Immediate containment: the first 15 minutes
Speed determines blast radius in a compromised AWS key incident. The first 15 minutes set the ceiling on how much damage the attacker can do — every action in this phase is designed to cut off attacker access while preserving the forensic evidence you need to investigate. You will use the AWS CLI and IAM console to deactivate the key, hunt for attacker-created backdoor credentials, and enable GuardDuty to generate real-time findings in parallel with your manual work. Complete all three steps before moving to the CloudTrail investigation phase.
Step 1: Deactivate the compromised key (minute 1)
aws iam update-access-key --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive --user-name [username]. If you do not know which IAM user owns the key, use aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE to identify the associated user before deactivating. Confirm deactivation: aws iam list-access-keys --user-name [username] should show Status: Inactive for the key.
Step 2: Revoke attacker sessions and check for new credentials (minutes 2-10)
The attacker may have used the key to create new IAM credentials. Check immediately: aws iam list-access-keys --user-name [username] (look for any second key created recently), aws iam list-users (check for new users created in the compromise window), and aws iam list-roles --query 'Roles[?CreateDate>=`2026-07-10`]' (new roles with suspicious trust policies). Delete any attacker-created IAM users and access keys before they can be used to regain access.
Step 3: Enable GuardDuty in all regions if not already enabled (minutes 10-15)
If GuardDuty is not active, enable it immediately via the GuardDuty console with one-click organization enablement. GuardDuty will begin detecting ongoing attacker activity within minutes of enablement, including crypto mining EC2 instances (CryptoCurrency:EC2/BitcoinTool.B), anomalous API calls (UnauthorizedAccess:IAMUser/TorIPCaller), and data exfiltration patterns. Do not wait until after the investigation — enable it now so it is generating findings in parallel with your manual investigation.
CloudTrail investigation: mapping the blast radius
Once the key is deactivated, the investigation focuses on answering two questions: what did the attacker access, and what did they create? CloudTrail is your primary source of truth, logging every authenticated API call with the access key ID as a queryable field. The investigation must cover all 30+ AWS regions because sophisticated attackers intentionally launch resources in non-primary regions to delay detection. You will use Athena queries against your S3-based CloudTrail logs for cross-region analysis, filtering first for high-impact events like IAM CreateUser, EC2 RunInstances, and CloudTrail StopLogging before expanding to the full event set.
Query CloudTrail for all events by access key ID
If you have an S3-based CloudTrail trail: use Athena to query across all regions and all time. Create the Athena table using the CloudTrail S3 location, then query: SELECT eventTime, eventName, awsRegion, sourceIPAddress, userAgent, errorCode FROM cloudtrail_logs WHERE useridentity.accesskeyid = 'AKIAIOSFODNN7EXAMPLE' AND eventtime >= '2026-07-01' ORDER BY eventTime. Focus on error-free events (errorCode IS NULL or errorCode = '') because successful API calls represent actual attacker actions. Errors indicate attempts that failed due to insufficient permissions.
High-priority events to search for
Data exfiltration: S3 GetObject, S3 ListBuckets, S3 GetBucketAcl, RDS CreateDBSnapshot, RDS RestoreDBInstanceFromDBSnapshot. Persistence: IAM CreateUser, IAM CreateAccessKey, IAM AttachUserPolicy, IAM PutUserPolicy, STS AssumeRole with external account IDs. Resource creation: EC2 RunInstances (crypto mining), Lambda CreateFunction, ECS RegisterTaskDefinition. Evidence destruction: CloudTrail StopLogging, CloudTrail DeleteTrail, CloudWatch DeleteAlarms. For each finding, note the region, resource IDs created, and source IP addresses for your incident report.
Check all regions for attacker-created EC2 instances
Crypto mining is the fastest monetization for attackers with EC2 access. Run this across all regions: for region in $(aws ec2 describe-regions --query 'Regions[*].RegionName' --output text); do instances=$(aws ec2 describe-instances --region $region --filters 'Name=instance-state-name,Values=running,pending,stopping' --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,LaunchTime,PublicIpAddress]' --output text 2>/dev/null); if [ -n "$instances" ]; then echo "=== $region ==="; echo "$instances"; fi; done. Any instances in regions you do not use, with instance types commonly used for mining (p3, g4dn, or compute-optimized), warrant immediate termination and tag-based cost investigation.
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Post-incident hardening
After containment and investigation, the goal is structural change — not policy commitments, but architectural decisions that make long-lived access keys unnecessary for the systems that previously depended on them. This phase covers replacing static access keys with IAM roles and OIDC federation for CI/CD pipelines and compute services, and enabling AWS Config managed rules to enforce key hygiene automatically going forward. These changes reduce the blast radius of any future credential exposure to a time-limited window rather than an indefinite compromise.
Replace access keys with IAM roles and OIDC federation
For every service currently using access keys: (1) EC2/Lambda/ECS: attach an IAM instance role or execution role — no access key needed. (2) GitHub Actions: configure OIDC federation (aws-actions/configure-aws-credentials@v4 with role-to-assume instead of aws-access-key-id). (3) Developer CLI access: configure IAM Identity Center and use aws sso login for temporary credentials. The goal is zero long-lived access keys in production. Audit remaining access keys: aws iam generate-credential-report; aws iam get-credential-report shows all IAM users with access keys and when they were last used.
Implement AWS Config rules for key hygiene
Enable these AWS Config managed rules to detect key hygiene issues before they become incidents: iam-access-keys-rotated (alerts if any access key is older than 90 days), iam-no-inline-policy (inline policies bypass the policy review workflow), iam-root-access-key-check (root account must have no access keys), and iam-user-no-policies-check (users should get permissions via groups, not direct policies). Set up auto-remediation to disable access keys older than 90 days and page the key owner for rotation.
The bottom line
AWS access key compromise response has one non-negotiable rule: deactivate before investigating. The investigation sequence then follows CloudTrail from the key ID across all 30+ AWS regions, hunting for attacker-created IAM credentials, compute resources, and data access. Complete the investigation before deleting the deactivated key, because the key ID is your primary filter. After the incident, eliminate long-lived access keys as a structural change — not as a policy, but by replacing them with IAM roles, OIDC federation, and temporary credentials that expire automatically and cannot be leaked in the same way.
Frequently asked questions
What is the first thing I should do when I discover an AWS access key has been leaked?
Deactivate the key immediately — before investigating what happened, before calling your manager, before reading any more of this guide. In AWS IAM console: navigate to IAM > Users > [username] > Security credentials > Access keys, find the leaked key, and click 'Make inactive'. Via CLI: aws iam update-access-key --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive --user-name [username]. Deactivating (not deleting) keeps the key ID visible in logs so you can trace all historical activity. The attacker loses access the moment the key is deactivated, stopping any in-progress operations.
How do I find out what an attacker did with my compromised AWS access key?
Query AWS CloudTrail, which logs all API calls made with your AWS credentials. Search by the access key ID across all regions: aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIAIOSFODNN7EXAMPLE --start-time 2026-07-01T00:00:00Z --region us-east-1 --output json. Repeat this for every AWS region (there are 30+) because attackers frequently pivot to non-primary regions. For comprehensive cross-region analysis, use AWS CloudTrail Lake or Athena queries against S3-based CloudTrail logs if you have an organization-wide trail. Look for: EC2 RunInstances (crypto mining), IAM CreateUser/CreateAccessKey (new credentials for persistence), S3 GetObject/ListBuckets (data theft), and CloudTrail StopLogging/DeleteTrail (evidence destruction).
What if the attacker created new IAM users or access keys before I deactivated the original key?
Attackers who gain IAM access almost always create backdoor credentials immediately. Search CloudTrail for CreateUser, CreateAccessKey, and AttachUserPolicy events during the compromise window, filtering by the compromised access key ID. For each attacker-created IAM user: delete all associated access keys first, then delete the user. For each attacker-attached policy or role: remove the policy. Also check for new IAM roles with cross-account trust policies (a common persistence mechanism): aws iam list-roles | jq '.Roles[] | select(.AssumeRolePolicyDocument.Statement[].Principal.AWS != null) | {RoleName, Principal: .AssumeRolePolicyDocument.Statement[].Principal.AWS}'. Any role trusting an unknown external account ID is attacker-created.
Should I delete or just deactivate the compromised AWS access key?
Deactivate first, then delete after the investigation. Deactivating stops the attacker immediately while preserving the access key ID in IAM for correlation with CloudTrail logs during your investigation. If you delete immediately, you lose the ability to filter CloudTrail by access key ID (though the logs still exist, querying them becomes harder without the key ID). After your CloudTrail investigation is complete (typically 2-4 hours), delete the key permanently. Also rotate any other access keys associated with the same IAM user — the compromise of one key suggests the user's credentials may be more broadly exposed.
How do I check all AWS regions for resources created by the attacker?
Attackers frequently launch resources in non-primary regions to avoid detection. Check each region for new resources created during the compromise window. For EC2 instances: aws ec2 describe-instances --region [region] --filters 'Name=launch-time,Values=2026-07-10*' for each region. Automate with: for region in $(aws ec2 describe-regions --query 'Regions[*].RegionName' --output text); do echo $region; aws ec2 describe-instances --region $region --filters Name=launch-time,Values=2026-07-10 --query 'Reservations[*].Instances[*].[InstanceId,LaunchTime,PublicIpAddress,Tags]' --output table; done. Also check for new S3 buckets (aws s3api list-buckets) and Lambda functions in each region (aws lambda list-functions --region [region]).
What should I do if my AWS root account credentials are compromised?
Root account compromise is the most critical AWS security incident. Immediate steps: (1) If you still have root access, immediately change the root password and enable a hardware MFA device. (2) Revoke all root account access keys (root accounts should never have access keys — delete any that exist). (3) Review all IAM users and roles for new or modified trust relationships. (4) Check for organization-level changes: new member accounts created, SCPs modified, or delegated admin assignments changed. (5) Contact AWS Support immediately via the console — AWS has an abuse team that can help identify attacker activity and may have already detected automated abuse. (6) Engage AWS Incident Response (an available paid service) for severe root compromises.
How do I prevent AWS access key leaks from happening again?
Prevention requires eliminating long-lived access keys entirely where possible. Use IAM roles instead of access keys for all EC2 instances, Lambda functions, and ECS tasks — they rotate automatically and leave no key to leak. For CI/CD pipelines: use OIDC federation (GitHub Actions, GitLab CI, CircleCI all support it) to allow pipelines to assume an IAM role without a stored access key. For developer access: use AWS IAM Identity Center (SSO) with temporary credentials from the AWS CLI (aws sso login) rather than static access keys. For local development: set up aws-vault or 1Password CLI integration to inject temporary credentials rather than storing permanent credentials in ~/.aws/credentials. Implement GitHub's push protection and Gitleaks pre-commit hooks as a backstop.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
