The email lands from GitHub, not from AWS: a secret scanning alert, an AWS access key ID and secret detected in a commit that was pushed to a public repo forty minutes ago. Maybe it was a .env file that got added by accident, maybe it was hardcoded during a quick fix and never removed before the push. It doesn't matter how it got there. What matters now is that the key has been sitting in public for forty minutes, and forty minutes is enough time for automated scrapers that do nothing but watch public commits for exactly this pattern to have already found it.
The instinct a lot of people have here is to start investigating first, pull CloudTrail, figure out what happened, before touching anything. That instinct is backwards, and it's the single most common mistake in this exact scenario. The key is still live. Every minute spent investigating is another minute an attacker who already has it can keep using it. The first move, before anything else, is to deactivate or delete that access key in IAM. AWS's own incident response guidance says the same thing directly: contain first, investigate second. You can't accidentally destroy evidence by disabling a key, CloudTrail already logged everything it did.
Once the key is dead, the investigation is what actually determines how bad this is. Pull CloudTrail for every event tied to that specific access key ID, not just the account, the access key ID narrows it to exactly what this one credential did. Look for three things specifically, because they're the three moves that show up over and over in real credential-compromise cases. First, new IAM users, new access keys on existing users, or new roles, because creating a second, quieter credential is the standard way an attacker keeps access after the first key gets killed. Second, new EC2 instances or Lambda functions in regions your account doesn't normally use, because unauthorized compute for cryptomining is the most common thing a stolen AWS key gets used for. Third, if the key had any S3 permissions, check access logs for GetObject calls against buckets it shouldn't have been touching, since data pulled out during that window doesn't get undone by revoking the key afterward.
None of this works if the key had broad permissions to begin with, which is the actual lesson underneath the incident. A key scoped to exactly what one CI job needs limits how much a leak like this can do. A key that happens to have AdministratorAccess, because it was convenient when someone set it up eighteen months ago, turns "an access key leaked" into "every service in the account is now in scope for cleanup." The fix that prevents the next version of this isn't a smarter secret scanner, it's least-privilege IAM policies and, where possible, short-lived STS credentials instead of long-lived access keys that can sit valid in a public commit for however long it takes someone to notice.
This exact sequence, containment first, CloudTrail-driven investigation second, and the IAM hardening that shrinks the blast radius before it ever happens, is what the Cloud Security Engineer Handbook is built around across its incident response and IAM chapters for AWS and Azure: https://resources.codelivly.com/product/the-cloud-security-engineers-handbook/
Top comments (0)